使用TensorFlow实现DNN

这一节使用TF实现一个多层神经网络模型来对MNIST数据集进行分类,这里我们设计一个含有两个隐藏层的神经网络,在输出部分使用softmax对结果进行预测。

使用高级API实现多层神经网络

这里我们使用tensorflow.contrib包,这是一个高度封装的包,里面包含了许多类似seq2seq、keras一些实用的方法。
先引入数据

from tensorflow.examples.tutorials.mnist import input_data mnist = input_data.read_data_sets("./") #自动下载数据到这个目录 X_train = mnist.train.images X_test = mnist.test.images y_train = mnist.train.labels.astype("int") y_test = mnist.test.labels.astype("int") >>X_train array([[ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], ..., [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.], [ 0., 0., 0., ..., 0., 0., 0.]], dtype=float32) >>len(X_train) 55000 >>len(X_train[0]) 784 >>X_train[0] array([ 0., 0., 0., ..., 0., 0., 0.], dtype=float32) >>y_test array([7, 2, 1, ..., 4, 5, 6])

模型的主要代码

features_cols = tf.contrib.learn.infer_real_valued_columns_from_input(X_train) dnn_clf = tf.contrib.learn.DNNClassifier(hidden_units=[300,100], n_classes=10, feature_columns=features_cols) dnn_clf.fit(X_train, y_train, batch_size=50, steps=10000) from sklearn.metrics import accuracy_score y_pred = dnn_clf.predict(X_test) print(accuracy_score(y_test, list(y_pred)))

其中infer_real_valued_columns_from_input这个方法根据名字可以看出,它是根据输入的数据来推算出数据的类型,该例子中features_cols的值为
[_RealValuedColumn(column_name='', dimension=784, default_value=None, dtype=tf.float32, normalizer=None)],短短几行代码就实现了一个多层神经网络模型。并且可能会发现上面这些与之前介绍的有些不同,不需要对变量进行初始化,不需要创建session,使用起来十分的简单。

使用TF实现多层神经网络

高度封装的API调用起来固然很爽,但是自己不了解内部的原理使用起来就不是那么的踏实,下面就使用TF实现同样的模型,代码主要分为两部分,构建TF计算流图和执行计算图。希望读者能够对比上面的代码来看接下来的部分。

构建TF计算流图

首先我们需要根据输入的数据来设定输入的参数,使用的数据集MNIST为28*28的矩阵,整个神经网络包含两个隐藏层

n_inputs = 28 * 28 n_hidden1 = 300 n_hidden2 = 100 n_output = 10 X = tf.placeholder(tf.float32,shape=(None,n_inputs),name='X') y = tf.placeholder(tf.int64,shape=(None),name='y')#注意数据类型

上面使用占位符的方法来声明模型的输入X和y,需要注意的是占位符的数据类型,在执行阶段,占位符会被输入的数据所替代。接下来我们需要创建模型的两个隐藏层和输出层,两个隐藏使用Relu作为激活函数,输出层使用softmax。每一层需要指定节点的个数。

def neuron_layer(X,n_neurons,name,activation=None): with tf.name_scope(name): n_inputs = int(X.get_shape()[1]) #特征个数 stddev = 2 / np.sqrt(n_inputs) init = tf.truncated_normal((n_inputs,n_neurons),stddev=stddev) W = tf.Variable(init,name='weight') b = tf.Variable(tf.zeros([n_neurons]),name='baise') z = tf.matmul(X,W) + b if activation == "relu": return tf.nn.relu(z) else: return z

我将逐行的对上面代码进行解释:

1.为了方便在TensorBoard上面查看,每一层的神经网络都创建一个name_scope。这一步是可选操作,如果不需要在TensorBoard查看那就可以忽略掉。

2.根据输入的数据的形状来获取数据的特征个数(第二个维度)

3.接下来的代码是创建权重矩阵W和偏置b,权重W不能使用0进行初始化,这样会导致所有的神经元的输出为0,出现对称失效问题,这里使用truncated normal分布(Gaussian)来初始化权重,

tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None) 通过指定均值和标准方差来生成正态分布,抛弃那些大于2倍stddev的值。这样将有助于加快训练速度。在初始化b的时候,每一层只有一个偏置,我们全部设置为0,这样并不会出现对称失效问题。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/13117.html