我正在研究蛋白质序列。我的目标是建立一个卷积网络,预测蛋白质中每个氨基酸的三个角度。我在调试需要重塑操作的TFLearn DNN模型时遇到了问题。
输入数据描述(当前)25种不同长度的蛋白质。要使用张量,我需要有统一的尺寸,所以我用零填充空输入单元格。每个氨基酸由4维代码表示。除了帮助您了解张量的形状之外,其中的细节可能并不重要。
DNN的输出是六个数字,代表三个角度的正弦和余弦。为了创建有序对,DNN图将[...,6] Tensor重新整形为[...,3,2]。我的目标数据以相同的方式编码。我用余弦距离来计算损失。
我构建了一个非卷积DNN,它表现出良好的初始学习行为,这与我将在此处发布的代码非常相似。但该模型孤立地处理了三个相邻的氨基酸。我想将每种蛋白质作为一个整体来对待 - 最初滑动窗口宽3个氨基酸,最终变大。
现在我正在转换为卷积模型,我似乎无法获得匹配的形状。以下是我的代码的工作部分:
import tensorflow as tf
import tflearn as tfl
from protein import ProteinDatabase # don't worry about its details
def backbone_angle_distance(predict, actual):
with tf.name_scope("BackboneAngleDistance"):
actual = tfl.reshape(actual, [-1,3,2])
# Supply the -1 argument for axis that TFLearn can't pass
loss = tf.losses.cosine_distance(predict, actual, -1,
reduction=tf.losses.Reduction.MEAN)
return loss
# Training data
database = ProteinDatabase("./data")
inp, tgt = database.training_arrays()
# DNN model, convolution only in topmost layer for now
net = tfl.input_data(shape=[None, None, 4])
net = tfl.conv_1d(net, 24, 3)
net = tfl.conv_1d(net, 12, 1)
net = tfl.conv_1d(net, 6, 1)
net = tfl.reshape(net, [-1,3,2])
net = tf.nn.l2_normalize(net, dim=2)
net = tfl.regression(net, optimizer="sgd", learning_rate=0.1, \
loss=backbone_angle_distance)
model = tfl.DNN(net)
# Generate a prediction. Compare shapes for compatibility.
out = model.predict(inp)
print("\ninp : {}, shape = {}".format(type(inp), inp.shape))
print("out : {}, shape = {}".format(type(out), out.shape))
print("tgt : {}, shape = {}".format(type(tgt), tgt.shape))
print("tgt shape, if flattened by one dimension = {}\n".\
format(tgt.reshape([-1,3,2]).shape))
此时的输出是:
inp : <class 'numpy.ndarray'>, shape = (25, 543, 4)
out : <class 'numpy.ndarray'>, shape = (13575, 3, 2)
tgt : <class 'numpy.ndarray'>, shape = (25, 543, 3, 2)
tgt shape, if flattened by one dimension = (13575, 3, 2)
因此,如果我重塑4D Tensor tgt ,将最外层维度展平, out 和 tgt 应匹配。由于TFLearn的代码生成批次,我尝试拦截并重塑我的自定义丢失函数backbone_angle_distance()的第一行中的Tensor 实际。
如果我添加几行来尝试模型拟合,如下所示:
e, b = 1, 5
model.fit(inp, tgt, n_epoch=e, batch_size=b, validation_set=0.2, show_metric=True)
我得到以下额外输出和错误:
---------------------------------
Run id: EEG6JW
Log directory: /tmp/tflearn_logs/
---------------------------------
Training samples: 20
Validation samples: 5
--
--
Traceback (most recent call last):
File "exp54.py", line 252, in <module>
model.fit(inp, tgt, n_epoch=e, batch_size=b, validation_set=0.2, show_metric=True)
File "/usr/local/lib/python3.5/dist-packages/tflearn/models/dnn.py", line 216, in fit
callbacks=callbacks)
File "/usr/local/lib/python3.5/dist-packages/tflearn/helpers/trainer.py", line 339, in fit
show_metric)
File "/usr/local/lib/python3.5/dist-packages/tflearn/helpers/trainer.py", line 818, in _train
feed_batch)
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/client/session.py", line 789, in run
run_metadata_ptr)
File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/client/session.py", line 975, in _run
% (np_val.shape, subfeed_t.name, str(subfeed_t.get_shape())))
ValueError: Cannot feed value of shape (5, 543, 3, 2) for Tensor 'TargetsData/Y:0', which has shape '(?, 3, 2)'
在我的代码中,我指定TargetsData / Y:0具有形状(?,3,2)?我知道它不会。根据追溯,我实际上似乎从未在backbone_angle_distance()中达到我的重塑操作。
感谢任何建议,谢谢!
答案 0 :(得分:0)
您需要像tgt
tgt = tgt.reshape([-1,3,2])
目标的维度应与此行定义的网络输出维度相同:
net = tfl.reshape(net, [-1,3,2])
。
答案 1 :(得分:0)
好吧,看起来我正在回答我自己的问题。
我尝试了Geert所建议的各种排列,但我无法做任何事情。当我在构建我在此讨论的网络之前的非卷积网络时,尝试将训练数据重新整形为[-1,3,2]是合适的。最后,我得出结论,TFLearn不会让我在损失函数中压缩CNN需要的4D Tensor。我需要像以前一样添加一个维度。但不是保留一个维度(这是-1的作用),现在我必须保留两个维度。
这是我的解决方案。
1)消除损失函数的重塑:
def backbone_angle_distance(predict, actual):
with tf.name_scope("BackboneAngleDistance"):
# Supply the -1 argument for axis that TFLearn can't pass
loss = tf.losses.cosine_distance(predict, actual, -1,
reduction=tf.losses.Reduction.MEAN)
return loss
2)引入变量 shp ,它明确存储4D输入Tensor的维度:
net = tfl.input_data(shape=[None, None, 4])
shp = tf.shape(net) # <--- (new)
net = tfl.conv_1d(net, 24, window)
net = tfl.conv_1d(net, 12, 1)
net = tfl.conv_1d(net, 6, 1)
net = tfl.reshape(net, [shp[0], shp[1], 3, 2]) # <--- (new)
net = tf.nn.l2_normalize(net, dim=2)
net = tfl.regression(net, optimizer="sgd", learning_rate=0.1, \
loss=backbone_angle_distance_1)
model = tfl.DNN(net)
我之前遇到的与形状有关的错误现在已经消失了。但如果有人仍在关注此事,我还有其他问题。
a)我做了吗?#34;对&#34;?这个算法可能永远不会在分布式系统上进行训练,因为我所拥有的数据集太小而不能打扰。但是,据我所知,TensorFlow图使用的任何东西本身都不是TensorFlow对象,有可能破坏可执行的任何并行化优化。 shp 是否是正确的TensorFlow对象?它通过切片操作得到的元素怎么样?
b)如果我在Numpy工作,这看起来像Python的省略号运算符。我甚至无意识地使用省略号在本讨论的顶部写下了我对Tensor形状的初步描述。 TensorFlow是否理解省略号?它可能很有用。