Tensorflow 使用Bidirectional()包装器构建双向LSTM模型,预测DNA序列功能

循环神经网络(RNN)

循环神经网络RNN能处理时间序列,过去几年中,应用 RNN 在语音识别,语言建模,翻译,图片描述等问题上已经取得一定成功,并且这个列表还在增长。RNN模型的一个代表是LSTM ,这是一种特别的 RNN,比标准的 RNN 在很多的任务上都表现得更好,因此获得了非常多的应用。值得一提的是,lstm的作者也Jürgen Schmidhuber 也是机器学习领域的大牛,名气比三巨头稍微低一些。该大牛和GAN的发明者Ian Goodfellow 之间有些互怼冲突,感兴趣的朋友可以查看这个文章从PM到GAN——LSTM之父Schmidhuber横跨22年的怨念(文字版)

双向循环神经网络(BRNN)

RNN和LSTM都只能依据之前时刻的时序信息来预测下一时刻的输出,但在有些问题中,当前时刻的输出不仅和之前的状态有关,还可能和未来的状态有关系。比如预测一句话中缺失的单词不仅需要根据前文来判断,还需要考虑它后面的内容,真正做到基于上下文判断。BRNN有两个RNN上下叠加在一起组成的,输出由这两个RNN的状态共同决定。因此BRNN是综合前后的信息来训练模型,在DNA结构预测等应用很多。关于BRNN可以参考这篇文章通俗易懂理解——双向LSTM.

使用双向LSTM预测DNA序列

将DNA序列用one_hot编码后,使用lstm和卷积神经网络连用可以用来预测DNA的功能,本代码试图复制论文“DanQ: a hybrid convolutional and recurrent deep neural network for quantifying the function of DNA sequences (Nucleic Acids Research, 2016, Vol. 44, No. 11 e107)“的网络结构,供感兴趣大家参考。one-hot编码请看本人文章字符串(如DNA序列,蛋白质序列)的编码和用于机器学习和神经网络
网络结构:
在这里插入图片描述

代码:

import tensorflow as tf
from tensorflow.keras import datasets, layers, optimizers, Sequential, metrics
import numpy as np
from scipy import sparse
import os

os.environ["CUDA_VISIBLE_DEVICES"] = "0"

#导入要训练的数据
allmatrix = sparse.load_npz('allmatrix_sparse.npz').toarray().astype('float32') # 稀疏矩阵存储的数据
allmatrix = allmatrix.reshape(21030, 2000, 4) # one-hot编码
target = np.load('target.txt.npy')

x = tf.convert_to_tensor(allmatrix)
y = tf.convert_to_tensor(target, dtype=tf.int32)

# 分训练集,验证集,测试集(70:10:20)
idx = tf.range(allmatrix.shape[0])
idx = tf.random.shuffle(idx)
x_train, y_train = tf.gather(x, idx[:int(0.7 * len(idx))]), tf.gather(y, idx[:int(0.7 * len(idx))])
x_val, y_val = tf.gather(x, idx[int(0.7 * len(idx)):int(0.8 * len(idx))]), tf.gather(y, idx[int(0.7 * len(idx)):int(
    0.8 * len(idx))])
x_test, y_test = tf.gather(x, idx[int(0.8 * len(idx)):]), tf.gather(y, idx[int(0.8 * len(idx)):])

batchsz = 256

db = tf.data.Dataset.from_tensor_slices((x_train, y_train))
db = db.shuffle(6000).batch(batchsz).repeat()
db_val = tf.data.Dataset.from_tensor_slices((x_val, y_val))
db_val = db_val.batch(batchsz)
db_test = tf.data.Dataset.from_tensor_slices((x_test, y_test))
db_test = db_test.batch(batchsz)

#构建双向LSTM
forward_lstm = layers.LSTM(320, return_sequences=True, unroll=True) # go_backwards 默认为false
backward_lstm = layers.LSTM(320,go_backwards=True,return_sequences=True, unroll=True)
 # 注意前后lstm的 go_backwards 必须设置不同,一个为false一个为true
 
brnn = layers.Bidirectional(forward_lstm,merge_mode='concat',backward_layer=backward_lstm)

# 构建全局网络,包含卷积层,池化层,双向LSTM层
network = Sequential([layers.Conv1D(320, kernel_size=26, padding='valid', activation=tf.nn.relu), #1D卷积
                      layers.MaxPooling1D(13, 13), # 1D 池化层
                      layers.Dropout(0.2),
                      brnn, # 双向lstm
                      layers.Flatten(),
                      layers.Dense(64, activation=tf.nn.relu), 
                      layers.Dropout(0.4),
                      layers.Dense(1, activation='sigmoid')])
# 查看网络结构
network.build(input_shape=(None, 2000, 4))
network.summary()

# 编译网络
network.compile(optimizer=optimizers.Adam(lr=0.5),
                loss=tf.keras.losses.BinaryCrossentropy(),
                metrics=['accuracy']
                )
# 训练网络
network.fit(db, epochs=200, validation_data=db_val,
            validation_steps=2, steps_per_epoch=x_train.shape[0]//batchsz)

# 测试网络
network.evaluate(db_test)

猜你喜欢

转载自blog.csdn.net/weixin_44022515/article/details/104257232
今日推荐