利用python和TensorFlow构建神经网络解决二分类问题

本文示例的模块版本:
python 3.6
tensorflow 1.15(会有很多警告,但不妨碍运行。另2.0很坑,API都变了T-T)

关于神经网络结构的软件设计和分类曲线的绘制,本文主要参考了以下文章:

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观察训练后的输出结果进行确认。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值