deepchem.models.sequentialではグラフ構造を読み取れなかった話
注意
この記事を読んでも特に得るものはありません。ただdeepchem2.1.0ではsequentialにグラフ畳み込みが出来なかったというだけの話です。
概要
deepchem 2.1.0
python2.7
model=deepchem.models.Sequential() """ model.fit() → model._create_graph(self, feature_shape, label_shape) shapeは勝手に推論してくれる. → model._layer_listをfor文で回して各layer.in_layerに1個前のlayerとして定義していく. 最終的なlayerをoutputして保存. → TensorGraph.built()で各layerがbuild()される. →以下略 """
model._create_graphの中身
def _create_graph(self, feature_shape, label_shape): """This is called to create the full TensorGraph from the added layers.""" if self.built: return # The graph has already been created. # Add in features features = Feature(shape=feature_shape) # Add in labels labels = Label(shape=label_shape) # Add in all layers prev_layer = features if len(self._layer_list) == 0: raise ValueError("No layers have been added to model.") for ind, layer in enumerate(self._layer_list): if len(layer.in_layers) > 1: raise ValueError("Cannot specify more than one " "in_layer for Sequential.") layer.in_layers += [prev_layer] prev_layer = layer # The last layer is the output of the model self.outputs.append(prev_layer) if self._loss_function == "binary_crossentropy": smce = SoftMaxCrossEntropy(in_layers=[labels, prev_layer]) self.set_loss(ReduceMean(in_layers=[smce])) elif self._loss_function == "mse": mse = ReduceSquareDifference(in_layers=[prev_layer, labels]) self.set_loss(mse) else: # TODO(rbharath): Add in support for additional # losses. raise ValueError("Unsupported loss.") self.build()
debugの試み(まだ何も気づいていない時)
model=Sequential(loss="binary_crossentropy") model.add(GraphConv(out_channel=2)) model.add(GraphGather(32, activation_fn="sigmoid")) model.fit(train, nb_epoch=1)
以下がエラー
TypeError Traceback (most recent call last) <ipython-input-151-eccebc8e26f4> in <module>() 2 model.add(GraphConv(out_channel=2)) 3 model.add(GraphGather(32, activation_fn="sigmoid")) ----> 4 model.fit(train, nb_epoch=1) 5 ~/deepchem/models/tensorgraph/sequential.pyc in fit(self, dataset, **kwargs) 78 """ 79 X_shape, y_shape, _, _ = dataset.get_shape() ---> 80 self._create_graph((None,) + X_shape[1:], (None,) + y_shape[1:]) 81 super(Sequential, self).fit(dataset, **kwargs) 82 ~/deepchem/models/tensorgraph/sequential.pyc in _create_graph(self, feature_shape, label_shape) 114 raise ValueError("Unsupported loss.") 115 --> 116 self.build() 117 118 def make_estimator(self, ~/deepchem/models/tensorgraph/tensor_graph.pyc in build(self) 665 for layer in self.topsort(): 666 with tf.name_scope(layer.name): --> 667 layer.create_tensor(training=self._training_placeholder) 668 self.rnn_initial_states += layer.rnn_initial_states 669 self.rnn_final_states += layer.rnn_final_states ~/deepchem/models/tensorgraph/layers.pyc in create_tensor(self, in_layers, set_tensors, **kwargs) 2586 b_list = self.variables[self.num_deg:] 2587 else: -> 2588 W_list, b_list = self._create_variables(in_channels) 2589 2590 # Extract atom_features ~/deepchem/models/tensorgraph/layers.pyc in _create_variables(self, in_channels) 2564 initializations.glorot_uniform( 2565 [in_channels, self.out_channel], name='kernel') -> 2566 for k in range(self.num_deg) 2567 ] 2568 b_list = [ ~/deepchem/models/tensorgraph/initializations.pyc in glorot_uniform(shape, name) 59 def glorot_uniform(shape, name=None): 60 fan_in, fan_out = get_fans(shape) ---> 61 s = np.sqrt(6. / (fan_in + fan_out)) 62 return uniform(shape, s, name=name) 63 TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
どうやら_create_graphが出来てないみたいなので少し確認.
layerのリスト表示.
model._layer_list
[<deepchem.models.tensorgraph.layers.GraphConv at 0x1a395577d0>, <deepchem.models.tensorgraph.layers.GraphGather at 0x1a32d2f8d0>]
さらに、in_layer, outputsの表示. エラー的にはどこかのin_layerの定義がおかしそう?
print(model._layer_list[0].in_layers) print(model._layer_list[1].in_layers) print(model.outputs)
[<deepchem.models.tensorgraph.layers.Feature object at 0x1a3f89f450>] [<deepchem.models.tensorgraph.layers.GraphConv object at 0x1a3c72f3d0>] [<deepchem.models.tensorgraph.layers.GraphGather at 0x1a3c72f990>]
ソースコードを確認してみるとどうやらGraphConvのテンソル構築がうまくいっていないようです.
gc= model._layer_list[0] inputs = gc._get_input_tensors(gc.in_layers[0]()) #[<tf.Tensor 'Placeholder_20:0' shape=(?,) dtype=float32>] in_channels = inputs[0].get_shape() #TensorShape([Dimension(None)])
どうやらGraphConvに入れるサンプルの次元が無いよ、ということのようです。
そういえば、Sequentialのatom_featureの引数が無い......?
どうやらSequentialにはグラフ組めない......
ということで色々調べていたら、deepchem1.4まではSequentialGraphといってkearsっぽく書けたみたいなんですが、今となっては普通のnerural networkしか無理みたいですね. 以前触っていた時はdeepchem 1.4とかだったので気づいたら削除されていたようです. 悲しい. SequentialGraph絶対便利なのになんで消してしまったんだろうか。。。