您的位置:首页 > 其它

使用keras框架训练一个简单的深度学习模型——(一)线性模型解决分类问题

2019-03-09 16:39 746 查看

在udemy上上The complete self-drving car course,根据课程的教法训练了一个最简单的深度学习模型,本文详细记录训练此模型的每个步骤以及代码含义。

源代码下载:https://download.csdn.net/download/rance_king/11008565

  1. 导入包,keras.models 导入的是Sequential模型,keras.layers导入了一种叫Dense的层,这是一种每个单元都与上,下一层的每个单元有连接的层,每个单元都完全地建立连接就是这个层的形式,Adam是一种优化器。
    import numpy as np
    import keras
    import matplotlib.pyplot as plt
    from keras.models import Sequential
    from keras.layers import Dense
    from keras.optimizers import Adam
  2. 放入一些初始数据。这个初始数据是我们手动设定然后放进来的。这个数据为了故意制作成方便训练一个线性模型,将两堆点分别放置在一个近似斜对角线的位置上,并给这些数据对应打上了相应的标签
    #设定为500个点
    n_pts = 500
    #设定随机种子,这样以后重复运行时还会形成与第一次试验相同的随机数据。
    np.random.seed(0)
    #设定了两堆点,这两堆点分别以坐标轴(13,12)和(8,6)为中心进行高斯分布(normal distribution)
    #因为原本生成的np.array是x和y坐标分别成为两个array,所以将矩阵转置(把矩阵的shape中两个数值调换)
    #如此获得了Xa,Xb是两堆点的坐标
    Xa = np.array([np.random.normal(13, 2, n_pts),
    np.random.normal(12, 2, n_pts)]).T
    Xb = np.array([np.random.normal(8, 2, n_pts),
    np.random.normal(6, 2, n_pts)]).T
    #将两堆点的坐标堆叠,得到了一个包含所有点的坐标的矩阵
    X = np.vstack((Xa, Xb))
    #设置一个有500个0和500个1的矩阵,因为这个矩阵设置完成后同样呈现出(2, 1000)这样的形态,为了与坐标
    #矩阵对应,同样将其进行矩阵转置
    y = np.matrix(np.append(np.zeros(n_pts), np.ones(n_pts))).T
    #画出点来,在X这个矩阵中,前五百个点的横坐标是X[前五百行,第0列], 纵坐标是X[前五百行,第1列]
    #后五百个点的横坐标是X[后五百行,第0列], 纵坐标是X[后五百行,第1列]
    plt.scatter(X[:n_pts,0], X[:n_pts,1])
    plt.scatter(X[n_pts:,0], X[n_pts:,1])
  3. 使用keras框架组建深度学习网络,只要调一下参数就好了,过程及其简单。总结起来可以分为四个部分,第一个部分是实例化模型和优化器;第二个部分是添加神经网络的层;第三个部分是将前面的两者进行编译;最终将数据输入,令神经网络拟合数据。
    #实例化一个Sequential模型
    model = Sequential()
    #实例化一个优化器,learning rate设为0.1
    adam=Adam(lr = 0.1)
    #给model增加一个Dense层,这一层只有一个神经节点,输入的形状是(2,),即输入的是一维数组,
    #包含一个横坐标一个纵坐标,激活函数使用sigmoid
    model.add(Dense(<
    3ff7
    /span>units=1, input_shape=(2,), activation='sigmoid'))
    #进行编译,采用刚才实例化的adam优化器,损失函数选择‘binary_crossentropy’因为最终输出的类别只有两类,所以是用binary,metrics是用来评估学习效果的,评估的标准选择准确度‘accuracy’
    model.compile(adam, loss='binary_crossentropy', metrics=['accuracy'])
    #用数据对模型进行拟合,x是输入矩阵的数据,y是标签数据,verbose是在学习过程中输出一些提示,1开0关
    #batch_size是指每一批训练50个数据,也就是五十个点,按批量训练数据可以增加训练的效率
    #epochs指的是将全部数据遍历一遍的次数,这里选择将全部数据遍历100次
    #shuffle是每次训练数据的时候会选择不同的数据洗牌并加入批次,如此减轻gradient在局部变为0的情况
    h=model.fit(x=X, y=y, verbose=1, batch_size=50,epochs=100, shuffle='true')
  4. 查看学习训练的情况
    #查看 是history字典里面的['loss'], 小图例legend,标题loss,横坐标epoch
    plt.plot(h.history['loss'])
    plt.legend(['loss'])
    plt.title('loss')
    plt.xlabel('epoch')
  5. 定义绘制线性模型的函数,并绘制含有点和概率分布的图。
    #传入点的矩阵X,标签信息y,以及训练好的model
    def plot_decision_boundary(X, y, model):
    #这一步是使用linspace来作出一个x轴和y轴上的跨度,其意义为在x坐标轴和y坐标轴上均匀地分出若干等分
    #默认好像是五十等分,如此分别得到一个数组,包含了分别等分x轴和y轴的数的数组
    x_span = np.linspace(min(X[:,0]) - 1, max(X[:,0]) + 1)
    y_span = np.linspace(min(X[:,1]) - 1, max(X[:,1]) + 1)
    #用meshgrid的方法得到一个网格,实际上就是把x坐标与y坐标一一对应地混合
    #可以通过print得知,xx实际上就是五十个重复的x轴向数组,每个数组都从小到大递增并且在y轴方向上重复
    #而yy则是在x方向上重复五十次,而在y方向上递增,由xx和yy的一一对应正好可以形成一个网格
    xx, yy = np.meshgrid(x_span, y_span)
    #xx.ravel()将xx碾平为一维数组
    xx_, yy_ = xx.ravel(), yy.ravel()
    #np.c_的作用是连接矩阵,将两个矩阵里的同一列的数据连接,并转置为同一行,在这里的作用就是令
    #变量grid变成网格上每个点的坐标
    grid = np.c_[xx_, yy_]
    #对网格上均匀点的坐标用模型进行预测
    pred_func = model.predict(grid)
    #按照xx的形状进行变形,实际上xx的形状是(50,50),而此时grid的形状是(2500,2)
    #因为网格上一共2500个点,每个点有横纵坐标,故而如此
    z = pred_func.reshape(xx.shape)
    #最终使用contourf绘制出等高线,首先z是我们预测的概率分布的值,这个值会形成等高线,而xx,yy是坐标轴
    #形成网格的坐标,这个函数合起来如此使用是一个套路。
    plt.contourf(xx, yy, z)
    #执行函数并画出之前的点
    plot_decision_boundary(X, y, model)
    plt.scatter(X[:n_pts,0], X[:n_pts,1])
    plt.scatter(X[n_pts:,0], X[n_pts:,1])
  6. 最后使用模型来对某个点进行一下预测,并且绘制一下这个点在图上的情况
    x = 7.5
    y = 5
    
    point = np.array([[x, y]])
    prediction = model.predict(point)
    plt.plot([x], [y], marker='o', markersize=10, color="red")
    print("prediction is: ",prediction)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐