莫烦Python--Tensorflow Day2

这篇博客记录了在莫烦Python中学习TensorFlow时关于构建神经网络、训练结果可视化、优化器应用以及如何应对overfitting的笔记。通过示例解释了过度拟合在分类和回归问题中的表现,并介绍了TensorFlow的dropout方法作为解决方案。通过调整dropout的keep_prob参数,可以看到对减少overfitting的效果。
摘要由CSDN通过智能技术生成

以下是自己学习莫烦Python中的笔记

构建自己的神经网络

import tensorflow as tf
import numpy as np

def add_layer(inputs, in_size, out_size, activation_function=None):      # activation_function=None表示默认线性函数
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))         # 设置权重矩阵,in_size行,out_size列的矩阵,推荐用随机变量,比全0好
    biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)                  # 定义偏置项
    Wx_plus_b = tf.matmul(inputs, Weights) + biases                      # 未被激活
    if activation_function is None:                                      # 线性的不需要激活函数
        output = Wx_plus_b
    else:
        output = activation_function(Wx_plus_b)                          # 需要激活函数
    return output

'''构建数据'''
x_data = np.linspace(-1, 1, 300)[:, np.newaxis]                            # newaxis = None,添加维度,变成矩阵的形式
noise = np.random.normal(0, 0.05, x_data.shape)                          # 添加噪点,让它不完全拟合原来的函数
y_data = np.square(x_data) + 0.5 + noise                                 # 定义的y

'''定义一个输入层(1个神经元),隐藏层(10个神经元),输出层(1个神经元)的简单神经网络'''
'''xs,ys存在的意义是可配置,不把程序写死,解耦,这样可以改变模型的输入值,直接传不方便封装,模型就只能对x_data,y_data进行预测'''
xs = tf.placeholder(tf.float32, (None, 1))                                 # 输给train_step的值,xs,ys,这里的None后面就是batch_size,None表示随意什么值
ys = tf.placeholder(tf.float32, (None, 1))                                 # placeholder的作用是用来穿数据的,1是x_data,y_data的属性是1
l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu)
# 定义layer 1,调用添加层函数,传入数据:输入数据,输如神经元个数,输出神经元个数(从第一层进入隐藏层,一个进去,10个出来)
# 定义激活函数relu,相当于用10条直线去拟合一个抛物线
prediction = add_layer(l1, 10, 1, activation_function=None)
# 定义输出层,也就是预测曾,传入从隐藏层输出的10个神经元,传出prediction层输出的1个神经元,激活函数默认线性

'''定义损失函数'''
loss = tf.reduce_mean(tf.reduce_sum(tf.square(y_data-prediction),        # 真实值减去预测数据的平方求和再平均
                                    reduction_indices=[1]))              # reduction_indices=[1]表示结果压缩的方向,1表示列方向压缩
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(loss)
# 采用梯度下降的优化算法以0.1的学习率(优化的步长取值)每训练一次,对误差进行更正或提升,下次会有更好的结果

'''所有变量初始化,并启用会话设置'''
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

for i in range(10000):                                                    # train_step10000次
    # 这里我们可以采用小步骤执行,一次不处理全部的数据,可以解决并行数据量大
    sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
    if i % 100 == 0:
        print(sess.run(loss, feed_dict={xs: x_data, ys: y_data}))
        
'''
运行结果:
0.5493656
0.0107342955
0.0070284773
0.006592798
0.0063318294
0.006061059
0.005771474
0.005488769
0.005196031
0.0044501587
0.0042058867
0.004073246
0.003959596
0.0038633016
0.0037791408
0.0036934523
0.0036113774
0.0035319463
0.003464909
0.0034044054
0.0033475696
0.0032985774
0.0032570336
0.0032204872
0.0031877018
0.0031564569
0.0031279041
0.003102748
0.0030788844
0.0030579553
0.0030362464
0.0030177354
0.0030016755
0.002987475
0.0029756082
0.0029649814
0.0029550295
0.0029448003
0.0029357218
0.0029277373
0.0029169486
0.0029066761
0.0028959094
0.0028867824
0.0028785528
0.002870171
0.0028620618
0.0028546161
0.002847477
0.0028404433
0.002833517
0.0028268904
0.0028205125
0.0028145504
0.002808905
0.0028017273
0.0027929782
0.0027851863
0.0027749557
0.0027644003
0.0027537593
0.0027437778
0.0027352145
0.0027273197
0.0027202086
0.0027134544
0.0027047154
0.0026974839
0.002690782
0.0026839096
0.0026774737
0.0026713694
0.0026650357
0.0026573725
0.0026495687
0.0026424658
0.0026353367
0.0026287038
0.002622738
0.0026163943
0.002610145
0.002604464
0.002599055
0.0025937355
0.0025889135
0.0025844388
0.0025796301
0.0025742496
0.0025692824
0.002564779
0.0025596002
0.0025547268
0.0025502879
0.002546214
0.0025425574
0.0025390468
0.0025354468
0.0025319364
0.002528599
0.002525389
'''

训练结果可视化

'''结果可视化'''
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt

def add_layer(inputs, in_size, out_size, activation_function=None):      # activation_function=None表示默认线性函数
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))         # 设置权重矩阵,in_size行,out_size列的矩阵,推荐用随机变量,比全0好
    biases = tf.Variable(tf.zeros([1, out_size]) + 0.1)                  # 定义偏置项
    Wx_plus_b = tf.matmul(inputs, Weights) + biases                      # 未被激活
    if activation_function is None:                                      # 线性的不需要激活函数
        output = Wx_plus_b
    else:
        output = activation_function(Wx_plus_b)                          # 需要激活函数
    return output

'''构建数据'''
x_data = np.linspace(-1, 1, 300)[:, np.newaxis]                            # newaxis = None,添加维度,变成矩阵的形式
noise = np.random.normal(0, 0.05, x_data.shape)                          # 添加噪点,让它不完全拟合原来的函数
y_data = np.square(x_data) + 0.5 + noise                                 # 定义的y

'''定义一个输入层(1个神经元),隐藏层(10个神经元),输出层(1个神经元)的简单神经网络'''
'''xs,ys存在的意义是可配置,不把程序写死,解耦,这样可以改变模型的输入值,直接传不方便封装,模型就只能对x_data,y_data进行预测'''
xs = tf.placeholder(tf.float32, (None, 1))                                 # 输给train_step的值,xs,ys,这里的None后面就是batch_size,None表示随意什么值
ys = tf.placeholder(tf.float32, (None, 1))                                 # placeholder的作用是用来穿数据的,1是x_data,y_data的属性是1
l1 = add_layer(xs, 1, 10, activation_function=tf.nn.relu)
# 定义layer 1,调用添加层函数,传入数据:输入数据,输如神经元个数,输出神经元个数(从第一层进入隐藏层,一个进去,10个出来)
# 定义激活函数relu,相当于用10条直线去拟合一个抛物线
prediction = add_layer(l1, 10, 1, activation_function=None)
# 定义输出层,也就是预测曾,传入从隐藏层输出的10个神经元,传出prediction层输出的1个神经元,激活函数默认线性

'''定义损失函数'''
loss = tf.reduce_mean(tf.reduce_sum(tf.square(y_data-prediction),        # 真实值减去预测数据的平方求和再平均
                                    reduction_indices=[1]))              # reduction_indices=[1]表示结果压缩的方向,1表示列方向压缩
train_step = tf.train.GradientDescentOptimizer(0.05).minimize(loss)
# 采用梯度下降的优化算法以0.1的学习率(优化的步长取值)每训练一次,对误差进行更正或提升,下次会有更好的结果

'''所有变量初始化,并启用会话设置'''
init = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init)

fig = plt.figure()                          # 生成一个图片框
ax = fig.add_subplot(1, 1, 1)               # 给图片添加编号
ax.scatter(x_data, y_data)                  # 把原图生成散点图
plt.ion()                                   # show之后不暂停
plt.show()                                  # 显示

for i in range(10000):                                                    # train_step10000次
    # 这里我们可以采用小步骤执行,一次不处理全部的数据,可以解决并行数据量大
    sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
    if i % 100 == 0:
        # print(sess.run(loss, feed_dict={xs: x_data, ys: y_data}))       这个是显示真实值
        try:
            ax.lines.remove(lines[0])                                     # 先抹除第一条线,如果没有再继续进行下面的
        except Exception:
            pass
        prediction_value = sess.run(prediction, feed_dict={xs: x_data})   # 预测值
        lines = ax.plot(x_data, prediction_value, 'r-', lw=5)             # 把x_data和prediction_value用红色的线显示出来,宽度为5
        '''但是动态生成一次要抹掉一次,否则就会一直保存在图上'''
        plt.pause(0.1)                                                    # 暂停0.1秒再继续

运行源代码是个动态的过程

优化器加速神经网络训练

'''优化器Optimizer加速神经网络训练'''
'''
计算量太大了
    最基础的方法是---Stochatic Gradient Descent(SGD)随机梯度下降
    一次训练全部数据数据量太大,所以采用mini batch,每次使用一小部分训练数据调参
    1.传统的权重W = W(原始的)+(-Learning rate)*dx(校正值)
    2.Momentum的更新方法:m = b1*m-Learning rate * dx  ;  W = W + m
    3.AdaGrad的方法: v = v + dx^2 , W = W - Learning rate*dx/v^(1/2),依赖于学习率,每次会有不同的学习率
    4.RMSProp的更新方法:Momentum(m=b1*m-Learning rate*dx)+AdaGrad(v=v+dx^2)---> v=b1*v+(1-b1)*dx^2 ; W = W-Learning rate*dx/v^(1/2)
    5.Adam优化器:
        m = b1 * m + (1-b1) * dx --------> Momentum(下坡属性)
        v = b2 * v + (1-b2) * dx^2-------> AdaGard(阻力属性)
        W = W - Learning rate * m/v^(1/2)--->m和v同时考虑在内
    迅速收敛
'''

怎么解决overfitting

Overfitting 也被称为过度学习,过度拟合。 它是机器学习中常见的问题。 举个Classification(分类)的例子。
在这里插入图片描述
图中黑色曲线是正常模型,绿色曲线就是overfitting模型。尽管绿色曲线很精确的区分了所有的训练数据,但是并没有描述数据的整体特征,对新测试数据的适应性较差。

举个Regression (回归)的例子,
在这里插入图片描述
第三条曲线存在overfitting问题,尽管它经过了所有的训练点,但是不能很好的反应数据的趋势,预测能力严重不足。 TensorFlow提供了强大的dropout方法来解决overfitting问题。

代码:
import tensorflow as tf
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelBinarizer

# load data
digits = load_digits()
X = digits.data
y = digits.target
y = LabelBinarizer().fit_transform(y)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.3)


def add_layer(inputs, in_size, out_size, layer_name, activation_function=None, ):
    # add one more layer and return the output of this layer
    Weights = tf.Variable(tf.random_normal([in_size, out_size]))
    biases = tf.Variable(tf.zeros([1, out_size]) + 0.1, )
    Wx_plus_b = tf.matmul(inputs, Weights) + biases

    '''here to dropout'''
    Wx_plus_b = tf.nn.dropout(Wx_plus_b, keep_prob)

    if activation_function is None:
        outputs = Wx_plus_b
    else:
        outputs = activation_function(Wx_plus_b, )
    tf.summary.histogram(layer_name + '/outputs', outputs)
    return outputs


# define placeholder for inputs to network
keep_prob = tf.placeholder(tf.float32)
xs = tf.placeholder(tf.float32, [None, 64])  # 8x8
ys = tf.placeholder(tf.float32, [None, 10])

# add output layer
l1 = add_layer(xs, 64, 50, 'l1', activation_function=tf.nn.tanh)
prediction = add_layer(l1, 50, 10, 'l2', activation_function=tf.nn.softmax)

# the loss between prediction and real data
cross_entropy = tf.reduce_mean(-tf.reduce_sum(ys * tf.log(prediction),
                                              reduction_indices=[1]))  # loss
tf.summary.scalar('loss', cross_entropy)
train_step = tf.train.GradientDescentOptimizer(0.5).minimize(cross_entropy)

sess = tf.Session()
merged = tf.summary.merge_all()
# summary writer goes in here
train_writer = tf.summary.FileWriter("logs/train", sess.graph)
test_writer = tf.summary.FileWriter("logs/test", sess.graph)

# tf.initialize_all_variables() no long valid from
# 2017-03-02 if using tensorflow >= 0.12
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()
sess.run(init)
for i in range(500):
    # here to determine the keeping probability
    sess.run(train_step, feed_dict={xs: X_train, ys: y_train, keep_prob: 0.5})
    if i % 50 == 0:
        # record loss
        train_result = sess.run(merged, feed_dict={xs: X_train, ys: y_train, keep_prob: 1})
        test_result = sess.run(merged, feed_dict={xs: X_test, ys: y_test, keep_prob: 1})
        train_writer.add_summary(train_result, i)
        test_writer.add_summary(test_result, i)

训练中keep_prob=1时,就可以暴露出overfitting问题。keep_prob=0.5时,dropout就发挥了作用。 我们可以两种参数分别运行程序,对比一下结果。

当keep_prob=1时,模型对训练数据的适应性优于测试数据,存在overfitting,输出如下: 红线是 train 的误差, 蓝线是 test 的误差.
在这里插入图片描述
当keep_prob=0.5时效果好了很多,输出如下:
在这里插入图片描述如果dropout之后还是不够理想可以尝试改小梯度下降的学习率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值