fantom_zona’s diary

Impact the world!!!

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絶対便利なのになんで消してしまったんだろうか。。。