关于神经网络结构的软件设计和分类曲线的绘制,本文主要参考了以下文章:
https://blog.csdn.net/lilong117194/article/details/79130032
构建的具体步骤如下:
步骤1. 建立数据源(样本库)——使用随机初始化的方式。由于需要进行逻辑分类,需要建立2个数据类,并合并在一起。如下:
num_points=1000 # 样本数目 vectors_set=[] x1_PlotData=[] # 用于后期绘图的数据 y1_PlotData=[] x2_PlotData=[] y2_PlotData=[] for i in range(int(num_points/2)): x1=np.random.normal(0.0,0.55) #横坐标,进行随机高斯处理化,以0为均值,以0.55为标准差 y1=x1*0.1+0.3+np.random.normal(-0.03,0.03) #纵坐标,数据点在y1=x1*0.1+0.3上小范围浮动 vectors_set.append([x1,y1,0]) x2 = np.random.normal(0.0, 0.55) y2 = x2 * 0.1 + 0.4 + np.random.normal(-0.03, 0.03) vectors_set.append([x2, y2,1]) x1_PlotData.append(x1) y1_PlotData.append(y1) x2_PlotData.append(x2) y2_PlotData.append(y2) x1_data=[v[0] for v in vectors_set] # 使用np.mat将list转化为numpy中的矩阵格式 x2_data=[v[1] for v in vectors_set] y_data=[v[2] for v in vectors_set] |
步骤2.建立数据流图:新建变量theta(同时建立正则项),假设函数tf.nn.relu ,代价函数(同时添加正则项),优化算法选择梯度下降法,并设置步长:
def get_weight(shape, lambda1): # 定义一个获取权重,并自动加入正则项到损失的函数。 var = tf.Variable(tf.random_normal(shape), dtype=tf.float32) # 生成一个变量 tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(lambda1)(var)) # add_to_collection()函数将新生成变量的L2正则化损失加入集合losses return var # 返回生成的变量
x_input=tf.placeholder(tf.float32,shape=[None,2]) # 定义神经网络输入和输出 y_input=tf.placeholder(tf.float32)
layer_dimension = [2,8,1] # 定义神经网络结构,即各个层的节点数目 n_layers = len(layer_dimension) # 获取神经网络的层数 cur_layer = x_input # 这个变量维护前向传播时最深层的节点,开始的时候就是输入层 in_dimension = layer_dimension[0] # 当前层的节点个数
for i in range(1, n_layers): # 循环生成网络结构 out_dimension = layer_dimension[i] # layer_dimension[i]为下一层的节点个数 weight = get_weight([in_dimension, out_dimension], 0.0001) # 生成当前层中权重的变量 bias = tf.Variable(tf.constant(0.1, shape=[out_dimension])) # 偏置 cur_layer = tf.nn.relu(tf.matmul(cur_layer, weight) + bias) # 使用Relu激活函数 in_dimension = layer_dimension[i] # 进入下一层之前将下一层的节点个数更新为当前节点个数
y= cur_layer # 最后一层的输出值即是总的输出值
mse_loss = tf.reduce_mean(tf.square(y_input - y)) # 在定义神经网络前向传播的同时已经将所有的L2正则化损失加入了图上的集合,这里是损失函数的定义。 tf.add_to_collection('losses', mse_loss) # 将均方误差损失函数加入损失集合 loss = tf.add_n(tf.get_collection('losses')) # get_collection()返回一个列表,这个列表是所有这个集合中的元素,在本样例中这些元素就是损失函数的不同部分,将他们加起来就是最终的损失函数 optimizer = tf.train.GradientDescentOptimizer(0.1) # 选择梯度下降法,并设置步长。 train_step = optimizer.minimize(loss) |
步骤3.初始化流图:
sess = tf.Session() init = tf.global_variables_initializer() sess.run(init) |
步骤4.开始训练,同时记录训练过程:
x_plot=[] y_plot=[] steps = 2000 for i in range(steps): xs=np.column_stack(( np.mat(x1_data).T,np.mat(x2_data).T)) ys = np.mat(y_data).T feed = { x_input: xs, y_input: ys } sess.run(train_step, feed_dict=feed) if i % 100 == 0 : print("After %d iteration:" % i) print("Cost: %f" % sess.run(loss, feed_dict=feed)) x_plot.append(i) y_plot.append(sess.run(loss, feed_dict=feed)) |
步骤5.输出训练结果,主要为训练参数theta和损失值(代价值):
print("Finnally Result") print("Loss: %f" % sess.run(loss, feed_dict=feed)) |
步骤6.在样本集中绘制训练后的分类线(采用绘制等高线的方式),和“训练次数-损失”曲线,以便观察训练结果:
xx,yy= np.mgrid[-2:2:0.1, 0.:0.8:0.02] grid = np.c_[xx.ravel(), yy.ravel()] probs = sess.run(y, feed_dict = { x_input: grid }) probs = probs.reshape(xx.shape) plt.subplot(1,2,1) plt.scatter(x1_PlotData,y1_PlotData,c='g') plt.scatter(x2_PlotData,y2_PlotData,c='r') plt.contour(xx, yy, probs, levels=[.5], cmap="Greys", vmin=0, vmax=.1) plt.subplot(1,2,2) plt.plot(x_plot,y_plot,'-') plt.show() |
输出结果:
Finnally Result Loss: 0.055836 |
输出图形: |
注:
由于两类点的互相干扰,如果训练的损失较高,有时会无法绘制出一条较好的等高线。可通过打印步骤6中的probs观察训练后的输出结果进行确认。