引入正则化优化网络模型的训练方法实践

作者: shaneZhang 分类: 机器学习的实践 发布时间: 2018-12-31 13:49
#coding=utf-8

# 用 300 x个符合正态分布的点 X[0, x1]作为数据集,根据点 X[x0, x1]计算生成标注 Y_,将数据集
# 标注为红色点和蓝色点。
# 标注规则为:当 x0^2 + x1^2 < 2 时,y_=1,标注为红色;当 x0^2 + x1^2 ≥2 时,y_=0,标注为蓝色。
# 我们分别用无正则化和有正则化两种方法,拟合曲线,把红色点和蓝色点分开。
# 在实际分类时, 如果前向传播输出的预测值 y 接近 1 则为红色点概率越大,
# 接近 0 则为蓝色点概率越大,输出的预 测值 y 为 0.5 是红蓝点概率分界线。

#导入门口,生成模拟数据集合
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

BATCH_SIZE=30
seed = 2

#基于seed产生随机数
rdm = np.random.RandomState(seed)
#随机数返回300行2列的矩阵,表示
X = rdm.randn(300,2)
#从这个300行2列的矩阵中取出一行,判断如果两个坐标的平方和小于2,给Y值赋值为1,其余赋值为0
#Y_作为输入数据集的标签(正确答案)
Y_ = [int(x0*x0 + x1*x1 < 2) for (x0,x1) in X]
#遍历Y中的每个元素,1赋值red,其余赋值为blue,这样就可以可视化的显示人可以直观的得到区分
Y_C =  [['red' if y else 'blue'] for y in Y_]
#对数据集X和Y进行Shape整理,第一个元素为-1表示,随第二个参数计算得到,第二个元素表述n行多少列,把X整理为n行2列的,把Y整理为n行1列的
X = np.vstack(X).reshape(-1,2)
Y_ = np.vstack(Y_).reshape(-1,1)
print X
print Y_
print Y_C

#用plt.scatter画出数据集X各行中的0列元素和第一列的元素点,即(X0,X1),用各行Y_C对应的值标识颜色
plt.scatter(X[:,0],X[:,1],c = np.squeeze(Y_C))
plt.show()

#定义神经网络的输入、参数和输出、定义前向传播的过程
def get_weight(shape,regularizer):
    w = tf.Variable(tf.random_normal(shape),dtype=tf.float32)
    tf.add_to_collection('losses',tf.contrib.layers.l2_regularizer(regularizer)(w))
    return w

def get_bias(shape):
    b = tf.Variable(tf.constant(0.01,shape=shape))
    return b

x = tf.placeholder(tf.float32,shape=(None,2))
y_ = tf.placeholder(tf.float32,shape=(None,1))

w1 = get_weight([2,11],0.01)
b1 = get_bias([11])
y1 = tf.nn.relu(tf.matmul(x,w1)+b1)

w2 = get_weight([11,1],0.01)
b2 = get_bias([1])
y = tf.matmul(y1,w2) + b2

#定义损失函数
loss_mse = tf.reduce_mean(tf.square(y - y_))
loss_total = loss_mse + tf.add_n(tf.get_collection('losses'))

#定义反向传播方法:不含正则化
train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_mse)

with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    STEPS = 40000
    for i in range(STEPS):
        start = (i * BATCH_SIZE) % 300
        end = start + BATCH_SIZE
        sess.run(train_step,feed_dict={x:X[start:end],y_:Y_[start:end]})
        if i % 2000 == 0:
            loss_mse_v = sess.run(loss_mse,feed_dict={x:X,y_:Y_})
            print "After %d steps, loss is:%f"%(i,loss_mse_v)
    #xx在-3到3之间以步长为0.001,yy在-3到3之间以步长为0.001,生成二维网格坐标点
    xx,yy = np.mgrid[-3:3:.01,-3:3:.01]
    #将xx ,yy 拉直,合并成一个2列的矩阵,得到一个网格坐标点的集合
    grid = np.c_[xx.ravel(),yy.ravel()]
    #将网格点喂入神经网络,probs为输出
    probs = sess.run(y,feed_dict={x:grid})
    #将probs的shape整理成xx的样子
    probs = probs.reshape(xx.shape)
    print "w1:\n",sess.run(w1)
    print "b1:\n",sess.run(b1)
    print "w2:\n",sess.run(w2)


plt.scatter(X[:,0],X[:,1],c=np.squeeze(Y_C))
plt.contour(xx,yy,probs,levels=[.5])
plt.show()

#定义反向传播方法:包含正则化
train_step = tf.train.AdamOptimizer(0.0001).minimize(loss_total)

with tf.Session() as sess:
    init_op = tf.global_variables_initializer()
    sess.run(init_op)
    STEPS = 40000
    for i in range(STEPS):
        start = (i * BATCH_SIZE) % 300
        end = start + BATCH_SIZE
        sess.run(train_step,feed_dict={x:X[start:end],y_:Y_[start:end]})
        if i % 2000 == 0:
            loss_v = sess.run(loss_total,feed_dict={x:X,y_:Y_})
            print "After %d steps,loss is :%f"%(i,loss_v)

    xx,yy = np.mgrid[-3:3:0.01,-3:3:0.01]
    grid = np.c_[xx.ravel(),yy.ravel()]
    probs = sess.run(y,feed_dict={x:grid})
    probs = probs.reshape(xx.shape)
    print "w1:\n",sess.run(w1)
    print "b1:\n",sess.run(b1)
    print "w2:\n",sess.run(w2)

plt.scatter(X[:,0],X[:,1],c=np.squeeze(Y_C))
plt.contour(xx,yy,probs,levels=[.5])
plt.show()

如果觉得我的文章对您有用,请随意打赏。如果有其他问题请联系博主QQ(909491009)或者下方留言!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注