我正在尝试使用TensorFlow创建一个多标签分类器。尽管如此,我在添加和连接隐藏层时遇到了麻烦。
我一直在遵循这个教程:http://jrmeyer.github.io/tutorial/2016/02/01/TensorFlow-Tutorial.html
我使用的数据是UCI的Iris数据,已编码为独热编码:
训练X [105,4]
5,3.2,1.2,0.25.5,3.5,1.3,0.24.9,3.1,1.5,0.14.4,3,1.3,0.25.1,3.4,1.5,0.2...
训练Y [105,3]
0,0,10,0,10,0,10,0,10,0,10,0,1...
我还使用了测试数据X和Y,它们分别是[45,4]和[45,3]。
这是我的Python代码:
import tensorflow as tfimport numpy as npimport tarfileimport osimport matplotlib.pyplot as pltimport time## 导入数据def csv_to_numpy_array(filePath, delimiter): return np.genfromtxt(filePath, delimiter=delimiter, dtype=None)trainX = csv_to_numpy_array("Iris_training_x.csv", delimiter=",").astype(np.float32)trainY = csv_to_numpy_array("Iris_training_y.csv", delimiter=",").astype(np.float32)testX = csv_to_numpy_array("Iris_testing_x.csv", delimiter=",").astype(np.float32)testY = csv_to_numpy_array("Iris_testing_y.csv", delimiter=",").astype(np.float32)# 数据集参数numFeatures = trainX.shape[1]numLabels = trainY.shape[1]# 训练会话参数numEpochs = 1000learningRate = tf.train.exponential_decay(learning_rate=0.008, global_step= 1, decay_steps=trainX.shape[0], decay_rate= 0.95, staircase=True)# 占位符X=tf.placeholder(tf.float32, [None, numFeatures])y=tf.placeholder(tf.float32, [None, numLabels])# 初始化权重和偏置Weights = tf.Variable(tf.random_normal([numFeatures, numLabels], mean=0, stddev=(np.sqrt(6 / numFeatures + numLabels + 1)), name="Weights"))bias = tf.Variable(tf.random_normal([1, numLabels], mean=0, stddev=(np.sqrt(6 / numFeatures + numLabels + 1)), name="bias"))# 预测算法(前馈)apply_weights_OP = tf.matmul(X, Weights, name="apply_weights")add_bias_OP = tf.add(apply_weights_OP, bias, name="add_bias")activation_OP = tf.nn.sigmoid(add_bias_OP, name="activation")numFeatures = activation_OPapply_weights_OP = tf.matmul(X, Weights, name="apply_weights")add_bias_OP = tf.add(apply_weights_OP, bias, name="add_bias")activation_OP = tf.nn.sigmoid(add_bias_OP, name="activation")init_OP = tf.initialize_all_variables()# 成本函数(均方误差)cost_OP = tf.nn.l2_loss(activation_OP-y, name="squared_error_cost")# 优化算法(梯度下降)training_OP = tf.train.GradientDescentOptimizer(learningRate).minimize(cost_OP)# 可视化epoch_values=[]accuracy_values=[]cost_values=[]# 开启交互式绘图plt.ion()# 创建主图fig = plt.figure()# 创建两个子图并设置标题ax1 = plt.subplot("211")ax1.set_title("训练准确率", fontsize=18)ax2 = plt.subplot("212")ax2.set_title("训练成本", fontsize=18)plt.tight_layout()# 创建TensorFlow会话sess = tf.Session()# 初始化所有TensorFlow变量sess.run(init_OP)## 用于可视化的操作# argmax(activation_OP, 1) 给出模型认为最可能的标签# argmax(y, 1) 是正确标签correct_predictions_OP = tf.equal(tf.argmax(activation_OP,1),tf.argmax(y,1))# False 为 0,True 为 1,我们的平均值是多少?accuracy_OP = tf.reduce_mean(tf.cast(correct_predictions_OP, "float"))# 回归输出的摘要操作activation_summary_OP = tf.histogram_summary("output", activation_OP)# 准确率的摘要操作accuracy_summary_OP = tf.scalar_summary("accuracy", accuracy_OP)# 成本的摘要操作cost_summary_OP = tf.scalar_summary("cost", cost_OP)# 检查变量(W, b)在每次迭代后如何更新的摘要操作weightSummary = tf.histogram_summary("Weights", Weights.eval(session=sess))biasSummary = tf.histogram_summary("biases", bias.eval(session=sess))# 合并所有摘要all_summary_OPS = tf.merge_all_summaries()# 摘要写入器writer = tf.train.SummaryWriter("summary_logs", sess.graph_def)# 初始化报告变量cost = 0diff = 1# 训练轮次for i in range(numEpochs): if i > 1 and diff < .0001: print("成本变化 %g;已收敛。"%diff) break else: # 运行训练步骤 step = sess.run(training_OP, feed_dict={X: trainX, y: trainY}) # 报告偶尔统计 if i % 10 == 0: # 将轮次添加到epoch_values epoch_values.append(i) # 在测试数据上生成准确率统计 summary_results, train_accuracy, newCost = sess.run( [all_summary_OPS, accuracy_OP, cost_OP], feed_dict={X: trainX, y: trainY} ) # 将准确率添加到实时绘图变量 accuracy_values.append(train_accuracy) # 将成本添加到实时绘图变量 cost_values.append(newCost) # 向写入器写入摘要统计 #writer.add_summary(summary_results, i) # 重新分配变量值 diff = abs(newCost - cost) cost = newCost # 生成打印语句 print("步骤 %d, 训练准确率 %g"%(i, train_accuracy)) print("步骤 %d, 成本 %g"%(i, newCost)) print("步骤 %d, 成本变化 %g"%(i, diff)) # 绘制进度到两个子图 accuracyLine, = ax1.plot(epoch_values, accuracy_values) costLine, = ax2.plot(epoch_values, cost_values) fig.canvas.draw() #time.sleep(1)# 我们对保留的测试数据的表现如何?print("测试集上的最终准确率:%s" %str(sess.run(accuracy_OP, feed_dict={X: testX, y: testY})))# 创建保存器saver = tf.train.Saver()# 将变量保存到.ckpt文件# saver.save(sess, "trained_variables.ckpt")# 关闭TensorFlow会话sess.close()
问题在这里:
# 预测算法(前馈)apply_weights_OP = tf.matmul(X, Weights, name="apply_weights")add_bias_OP = tf.add(apply_weights_OP, bias, name="add_bias")activation_OP = tf.nn.sigmoid(add_bias_OP, name="activation")numFeatures = activation_OPapply_weights_OP = tf.matmul(activation_OP, Weights, name="apply_weights")add_bias_OP = tf.add(apply_weights_OP, bias, name="add_bias")activation_OP = tf.nn.sigmoid(add_bias_OP, name="activation")
我的理解是,一层的输出应该连接到下一层的输入。我只是不知道如何修改层输出或输入;它总是给我这个兼容性错误:
/usr/bin/python3.5 /home/marco/PycharmProjects/NN_Iris/mainTraceback (most recent call last): File "/home/marco/PycharmProjects/NN_Iris/main", line 132, in <module> apply_weights_OP = tf.matmul(activation_OP, Weights, name="apply_weights") File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/math_ops.py", line 1346, in matmul name=name) File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/ops/gen_math_ops.py", line 1271, in _mat_mul transpose_b=transpose_b, name=name) File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/op_def_library.py", line 703, in apply_op op_def=op_def) File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py", line 2312, in create_op set_shapes_for_outputs(ret) File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/ops.py", line 1704, in set_shapes_for_outputs shapes = shape_func(op) File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/common_shapes.py", line 94, in matmul_shape inner_a.assert_is_compatible_with(inner_b) File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/tensor_shape.py", line 108, in assert_is_compatible_with % (self, other))ValueError: Dimensions 3 and 4 are not compatibleProcess finished with exit code 1
关于如何正确连接两个隐藏层有何建议?谢谢。
回答:
如果你想要一个具有一个隐藏层和一个输出层的全连接网络,它们的形状应该如下所示:
# 隐藏层weights_hidden = tf.Variable(tf.random_normal([numFeatures, num_nodes]))bias_hidden = tf.Variable(tf.random_normal([num_nodes]))preactivations_hidden = tf.add(tf.matmul(X, weights_hidden), bias_hidden)activations_hidden = tf.nn.sigmoid(preactivations_hidden)# 输出层weights_output = tf.Variable(tf.random_normal([num_nodes, numLabels]))bias_output = tf.Variable(tf.random_normal([numLabels])) preactivations_output = tf.add(tf.matmul(activations_hidden, weights_output), bias_output)
其中num_nodes
是你自己选择的隐藏层中的节点数。X
是一个[105, numFeatures]
矩阵,weights_hidden
是一个[numFeatures, num_nodes]
矩阵,所以第一隐藏层的输出是[105, num_nodes]
。同样,[105, num_nodes]
乘以[num_nodes, numLabels]
产生[105, numLabels]
输出。