TensorFlow学习程序(四):防止过拟合

	为了防止过拟合的发生,通常会使用正则化法或者dropout法来解决。
	首先给出使用dropou法防止过拟合的程序,该方法是随机选取一些神经元并将它们的激活值设置为0(即不参与之后的运算),同时维度保持不变,使得最终的参数数据由多个子训练集共同求出:
import tensorflow as tf
from sklearn.datasets import load_digits
from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import LabelBinarizer

#loading data
digits = load_digits()
X = digits.data #加载0-9数字图片
y = LabelBinarizer().fit_transform(digits.target) #原本01串中有10个0,0-9数字分别对应着将第0-9的位置换成1的01串
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = .3) #将数据集分为train和test两部分,前者生成预测,后者检验预测是否过拟合

def add_layer(inputs, in_size, out_size, layer_name, activation_function = None):  #构造神经网络层
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))
    biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)  #由于biases一般为不为0的数,所以再加上0.1
    Wx_plus_b = tf.matmul(inputs, Weights) + biases #相当于numpy中的np.dot(inputs, Weights)

    #dropout核心代码
    Wx_plus_b = tf.nn.dropout(Wx_plus_b, keep_prob)

    if activation_function is None: #如果没有激活函数,则为线性运算,outputs为Wx_plus_b
        outputs = Wx_plus_b
    else: #如果有激活函数,则需对Wx_plus_b进行进一步运算从而得到outputs
         outputs = activation_function(Wx_plus_b)
    tf.summary.histogram(layer_name + '/outputs', outputs)
    return outputs

keep_prob = tf.placeholder(tf.float32) #保持有百分之几的Wx_plus_b不会被dropout
xs = tf.placeholder(tf.float32, [None, 64]) #其中的64是因为输入数据是8*8的矩阵
ys = tf.placeholder(tf.float32, [None, 10]) #其中的10是因为输入数据是0-9,与prediction相对应

#构建输入层、隐藏层(黑箱部分)、输出层,对于输入层有几个data就有几个神经元,隐藏层神经元个数自定义
l1 = add_layer(xs, 64, 50, 'l1',  activation_function=tf.nn.tanh) #其中50是输出数据数量
prediction = add_layer(l1, 50, 10, 'l2', activation_function=tf.nn.softmax)
#其中xs是输入层的输入数据,prediction是输出层的输出数据,两个add_layer是隐藏层(黑箱部分)

cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), reduction_indices=[1]))

tf.summary.scalar('loss', cross_entropy) #与前面的tf.summary.histogram(layer_name + '/outputs', outputs)相对应

 train_step = tf.train.GradientDescentOptimizer(0.6).minimize(cross_entropy)

#激活定义的placeholder!
if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:
    init = tf.initialize_all_variables()
else:
    init = tf.global_variables_initializer()

with tf.Session() as sess:

    merged = tf.summary.merge_all() #将所有的summary保存到磁盘中

    #将数据写入logs文件中
    train_writer = tf.summary.FileWriter('logs/train', sess.graph)
    test_writer = tf.summary.FileWriter('logs/test', sess.graph)

    sess.run(init)

    for step in range(500):
        sess.run(train_step, feed_dict={xs: X_train, ys: y_train, keep_prob: 0.5})
        #向xs与ys中传值,利用placeholder的优点是可以将x(y)_data中的任意数量的数据传入,故可以实现数据的分批输入从而提高训练效率
        if step % 50 == 0:
            #record loss
            train_result = sess.run(merged, feed_dict={xs:X_train, ys:y_train, keep_prob: 0.5})
            test_result = sess.run(merged, feed_dict={xs: X_test, ys: y_test, keep_prob: 0.5})

            #将结果分别写入各自文件
            train_writer.add_summary(train_result, step)
            test_writer.add_summary(test_result, step)

	接下来给出使用正则化法防止过拟合,该方法是所有的参数数据加上惩罚项,惩罚力度的大小根正则化项中的参数lamda控制,从而控制模型的复杂程度,进而防止过拟合的发生:
import tensorflow as tf
from sklearn.datasets import load_digits
from sklearn.cross_validation import train_test_split
from sklearn.preprocessing import LabelBinarizer

# 将参数的正则化项加入到losses集合中
def regularizer(parameter):
    tf.add_to_collection("losses", tf.contrib.layers.l2_regularizer(0.1)(parameter))# lamda = 0.1
    return

#loading data
digits = load_digits()
X = digits.data #加载0-9数字图片
y = LabelBinarizer().fit_transform(digits.target) #原本01串中有10个0,0-9数字分别对应着将第0-9的位置换成1的01串
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = .3) #将数据集分为train和test两部分,前者生成预测,后者检验预测是否过拟合

def add_layer(inputs, in_size, out_size, layer_name, activation_function = None):  #构造神经网络层
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))
    regularizer(Weights)  # 将权重Weights的正则化项加入到losses集合中
    biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)  #由于biases一般为不为0的数,所以再加上0.1
    regularizer(biases)  # 将偏值biases的正则化项加入到losses集合中
    Wx_plus_b = tf.matmul(inputs, Weights) + biases #相当于numpy中的np.dot(inputs, Weights)

    if activation_function is None: #如果没有激活函数,则为线性运算,outputs为Wx_plus_b
        outputs = Wx_plus_b
    else: #如果有激活函数,则需对Wx_plus_b进行进一步运算从而得到outputs
         outputs = activation_function(Wx_plus_b)
    tf.summary.histogram(layer_name + '/outputs', outputs)
    return outputs

xs = tf.placeholder(tf.float32, [None, 64]) #其中的64是因为输入数据是8*8的矩阵
ys = tf.placeholder(tf.float32, [None, 10]) #其中的10是因为输入数据是0-9,与prediction相对应

#构建输入层、隐藏层(黑箱部分)、输出层,对于输入层有几个data就有几个神经元,隐藏层神经元个数自定义
l1 = add_layer(xs, 64, 50, 'l1',  activation_function=tf.nn.tanh) #其中50是输出数据数量
prediction = add_layer(l1, 50, 10, 'l2', activation_function=tf.nn.softmax)
#其中xs是输入层的输入数据,prediction是输出层的输出数据,两个add_layer是隐藏层(黑箱部分)

# 构建含有正则化项的交叉熵损失函数
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction), reduction_indices=[1]))
tf.add_to_collection("losses",cross_entropy)# 将不含有正则化项的损失函数加入losses集合中
cross_entropy = tf.add_n(tf.get_collection("losses"))# 将losses集合中的所有元素相加得到含有正则化项的损失函数(最终的损失函数)

tf.summary.scalar('loss', cross_entropy) #与前面的tf.summary.histogram(layer_name + '/outputs', outputs)相对应

train_step = tf.train.GradientDescentOptimizer(0.6).minimize(cross_entropy)

#激活定义的placeholder!
if int((tf.__version__).split('.')[1]) < 12 and int((tf.__version__).split('.')[0]) < 1:
    init = tf.initialize_all_variables()
else:
    init = tf.global_variables_initializer()

with tf.Session() as sess:

    merged = tf.summary.merge_all() #将所有的summary保存到磁盘中

    #将数据写入logs文件中
    train_writer = tf.summary.FileWriter('logs/train', sess.graph)
    test_writer = tf.summary.FileWriter('logs/test', sess.graph)

    sess.run(init)

    for step in range(500):
        sess.run(train_step, feed_dict={xs: X_train, ys: y_train})
        #向xs与ys中传值,利用placeholder的优点是可以将x(y)_data中的任意数量的数据传入,故可以实现数据的分批输入从而提高训练效率
        if step % 50 == 0:
            #record loss
            train_result = sess.run(merged, feed_dict={xs:X_train, ys:y_train})
            test_result = sess.run(merged, feed_dict={xs: X_test, ys: y_test})

            #将结果分别写入各自文件
            train_writer.add_summary(train_result, step)
            test_writer.add_summary(test_result, step)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值