1
I가 살펴 봉착

.. 분자 autoencoder 우리는 화합물 https://arxiv.org/pdf/1610.02415.pdf문자열 입출력 표현

용지가 입력을 받아 스트링 (텍스트 표현을 미소 구배 기반 최적화 보간 및 수행 할 분자의) 다음 그것을 변이 된 인코더를 사용하여 2D 잠재 공간으로 매핑합니다. 헥산 -3- 올 "CCCC (O) CC"공백 120 개 문자들이 패드 짧은 문자열 논문에서

위한

예 미소 문자열.

용지가

는 그런 다음 다시 미소 문자열로 3 정문 반복 단위 GRU 잠상 공간에 다음지도 위치를 사용하여 미소 스트링의 잠상 표현으로 1D 컨벌루션 네트워크 스택을 사용하여 문자열을 인코딩 .

이 백서를 이해하는 데있어 문제는 입력 및 출력 구조가 어떻게 보이는지를 결정하는 것입니다.

이 용지는 입력 및 출력 구조가 약간 모호합니다. 1 차원 전환 망의 사용으로 I는 입력 용지

RNN 디코더 드 인터넷 NES 확률 분포의 마지막 층 위에 말한다 출력을

'C' = 1 
'O' = 2 
'(' = 3 
')' =4 
' ' = 0 #for padding 

#so the hexan-3-ol smiles above would be 

[1,1,1,1,3,2,4,1,1,0...padding to fixed length] 

와 유사한 벡터화 표현이라고 생각 35 개 개의 가능한 미소 문자로 용지에 사용되는 (120)의 최대 미소 길이 미소 문자열

따라서 각각의 위치에서 가능한 모든 문자는 그 출력이 [120x35] 배열임을 의미 하는가?

그 논리를 앞으로 나르면 자동 입력기 대신에 입력이 평평한 [120 * 35] 배열임을 알 수 있습니다.

그와 내 문제는 자사가 도움 [120 * 35] 배열

감사 평탄화 경우 시퀀스의 다음 원자를 커버하기에 충분하지 않을 것이다 (9)의 최대 길이를 사용 1dConv이고 ...

답변

1

SMILES의 정의는 그래프의 선형 표현처럼 예상보다 복잡합니다.

https://en.wikipedia.org/wiki/Simplified_molecular-input_line-entry_system

짧은에서, 문자는 C = 탄소, O = 산소 등의 원자를 나타낸다. 그래프는 괄호로 분기 될 수있다. 즉, C (C) C는 "Y"구조를 형성한다. 마지막으로, 숫자로 표시된 클로저로 사이클을 만들 수 있습니다. 나는. "C1CCC1"은 사각형을 형성합니다 (즉, 문자 1은 다른 문자 1에 결합됩니다).

이 설명은 완전하지는 않지만 좋은 접지이어야합니다.

문자열이 유효한 미소 문자열 인 경우 다른 유효한 미소 문자열에 문자열을 추가하는 것만으로도 다른 유효한 문자열이 가장 많이 생성됩니다. 나는. "C1CC1"+ "C1CC1"=> "C1CC1C1CC1"이 유효합니다.

흔히 미소 문자열의 선형 부분을 추출하여 다른 문자열에 "포함"할 수 있으며 유효한 미소 문자열이 형성됩니다.

자동 엔코더가 배우고 있다고 생각하는 것은 이러한 변환을 수행하는 방법입니다. 예 부착 교체 할로겐 (염소, 브롬, 요오드)의 바보 예 이상일 수 :

C1CCC1Cl C1CCC1Br C1CCC1I

자동 인코더는 일정한 부분 및 가변 부분을 학습 - 그러나 선형 문자열 공간. 이제 완벽한 것은 아니며, 종이에서 주목한다면, 지속적으로 차별화 할 수있는 공간을 탐험 할 때 가장 가까운 유효한 웃음 문자열을 찾아야합니다.

당신이 미소 문자열을 탐구하려는 경우

는 논문에서 사용 된 것들 모두가 rdkit을 사용하여 생성 된 :

전체 공개에, 나는 유지하는 데 도움이,

https://github.com/rdkit/

. 잘하면이 도움이됩니다. (120

https://github.com/maxhodak/keras-molecules

나는 그것으로 주위를 연주되었고, 입력 및 출력 구조는 M이 SMILES 문자열의 최대 길이 인으로는 M × N 행렬은 다음과 같습니다

0

현재 소스 코드를 찾을 수 있습니다 이 경우)와 N은 문자 집합의 크기입니다. 각 행 M은 위치 M_i의 문자가 문자 N_j와 일치하는 위치를 제외하고는 0의 벡터입니다. 출력 행렬을 SMILE로 디코딩하려면 행 단위로 이동하여 문자 집합의 문자 위치와 일치시킵니다.

이 인코딩의 문제점은 많은 메모리를 차지한다는 점입니다. keras 이미지 반복기 접근 방식을 사용하면 다음을 수행 할 수 있습니다.

먼저 모든 미소를 세트의 각 미소에 대한 문자 세트 위치의 목록 인 '희소'형식으로 인코딩합니다.

이제 모든 SMILES (문자 집합)에 대해 정의 된 문자 집합이 생겼으며 각 SMILE은 이제 문자 집합의 각 문자 위치를 나타내는 숫자 목록입니다. 그런 다음 iterator를 사용하여 fit_generator 함수를 사용하여 케라 모델을 훈련하는 동안 즉시 수행 할 수 있습니다.

import numpy as np 
import threading 
import collections 

class SmilesIterator(object): 
    def __init__(self, X, charset, max_length, batch_size=256, shuffle=False, seed=None): 
     self.X = X 
     self.charset = charset 
     self.max_length = max_length 
     self.N = len(X) 
     self.batch_size = batch_size 
     self.shuffle = shuffle 
     self.batch_index = 0 
     self.total_batches_seen = 0 
     self.lock = threading.Lock() 
     self.index_generator = self._flow_index(len(X), batch_size, shuffle, seed) 

    def reset(self): 
     self.batch_index = 0 

    def __iter__(self): 
     return self 

    def _flow_index(self, N, batch_size, shuffle=False, seed=None): 
     self.reset() 
     while True: 
      if self.batch_index == 0: 
      index_array = np.arange(N) 
      if shuffle: 
       if seed is not None: 
        np.random.seed(seed + total_batches_seen) 
       index_array = np.random.permutation(N) 
      current_index = (self.batch_index * batch_size) % N 
      if N >= current_index + batch_size: 
       current_batch_size = batch_size 
       self.batch_index += 1 
      else: 
       current_batch_size = N - current_index 
       self.batch_index = 0 
      self.total_batches_seen += 1 
      yield(index_array[current_index: current_index + current_batch_size], 
      current_index, current_batch_size) 

    def next(self): 
     with self.lock: 
      index_array, current_index, current_batch_size = next(self.index_generator) 
     #one-hot encoding is not under lock and can be done in parallel 
     #reserve room for the one-hot encoded 
     #batch, max_length, charset_length 
     batch_x = np.zeros(tuple([current_batch_size, self.max_length, len(self.charset)])) 
     for i, j in enumerate(index_array): 
      x = self._one_hot(self.X[j]) 
      batch_x[i] = x 
     return (batch_x, batch_x) #fit_generator returns input and target 

    def _one_hot(self, sparse_smile): 
     ss = [] 
     counter = 0 
     for s in sparse_smile: 
      cur = [0] * len(self.charset) 
      cur[s] = 1 
      ss.append(cur) 
      counter += 1 
     #handle end of line, make sure space ' ' is first in the charset 
     for i in range(counter, len(self.charset)): 
      cur = [0] * len(self.charset) 
      cur[0] = 1 
      ss.append(cur) 
     ss = np.array(ss) 
     return(ss)