人工智能实战第六次作业_张绍恺

0.导航

项目内容
这个作业属于哪个课程人工智能实战
这个作业的要求在哪里人工智能实战第六次作业(个人)
我在这个课程的目标是开拓视野,积累AI实战经验
这个作业在哪个具体方面帮助我通过调整不同参数,研究其对于神经网络性能的影响,加深对神经网络以及其各个参数的理解和认识

1.具体作业内容

  • a. 将模型准确度调整至>97%
  • b. 整理形成博客,博客中给出参数列表和对应值
  • c. 给出最终的loss下降曲线
  • d. 给出最终准确度结果

2.过程及代码

- I.调整隐藏层神经元数量

首先测试隐藏层神经元数量,在此选择了[32, 64, 128]和[12, 32, 64]分别作为第一层和第二层的神经元数量,一共六组进行测试并绘制图表
代码(修改主函数为main函数并且在Test函数后添加返回值返回正确率correct_rate)和结果如下:

def main(LR, NH1, NH2, ME, BS):
    print("Loading...")
    learning_rate = LR
    n_hidden1 = NH1
    n_hidden2 = NH2
    n_output = 10
    dataReader = LoadData(n_output)
    n_images = dataReader.num_example
    n_input = dataReader.num_feature
    m_epoch =ME
    batch_size = BS
    dict_Param = InitialParameters3(n_input, n_hidden1, n_hidden2, n_output, 2)
    dict_Param = Train(dataReader, learning_rate, m_epoch, n_images, n_input, n_output, dict_Param, forward3, backward3, update3, batch_size)
    SaveResult(dict_Param)
    correct, num_images = Test(dataReader, n_output, dict_Param, n_input, forward3)
    return correct/num_images

if __name__ == '__main__':
    correct_rate = []
    n_hidden_list = ["32,16","64,16","128,16","64,32","128,32","128,64"]
    correct_rate.append(main(0.2, 32, 16, 2, 10))
    correct_rate.append(main(0.2, 64, 16, 2, 10))
    correct_rate.append(main(0.2, 128, 16, 2, 10))
    correct_rate.append(main(0.2, 64, 32, 2, 10))
    correct_rate.append(main(0.2, 128, 32, 2, 10))
    correct_rate.append(main(0.2, 128, 64, 2, 10))
    plt.figure()
    plt.plot(n_hidden_list, correct_rate)
    plt.xlabel("n_hidden")  
    plt.ylabel("correct_rate")
    plt.show()

1614471-20190422171532557-470483872.png

最高点是n_hidden1=64, n_hidden2=32的时候,结果为rate=9645 / 10000 = 0.9645,而n_hidden1=128, n_hidden2=64时结果为rate=9630 / 10000 = 0.963
可见隐藏层的神经元数量有时候并非越多越好,而可能在某个区间内有最佳效果,过犹不及

- II.调整学习率

注意到初始化会影响没次试验的结果,因此需要排除初始化的影响
其实做第一步调n_hidden参数的时候就发现这个问题了,但是因为初始化的参数本身就有n_hidden参与所以以我的水平暂时解决不了这个问题,当然确实经过多次的运行程序得到的结果中64, 32这一组的结果并不一定是最好的,有时候128, 64更好,还有时候甚至128, 32甚至128, 16之类的都作为某次测试的最佳结果出现过,我们姑且先用128, 64来做吧
改动的代码段如下

def main(LR, NH1, NH2, ME, BS, dP):
    print("Loading...")
    learning_rate = LR
    n_hidden1 = NH1
    n_hidden2 = NH2
    # n_output = 10
    # dataReader = LoadData(n_output)
    # n_images = dataReader.num_example
    # n_input = dataReader.num_feature
    m_epoch =ME
    batch_size = BS
    dict_Param = dP
    # dict_Param = InitialParameters3(n_input, n_hidden1, n_hidden2, n_output, 2)
    dict_Param = Train(dataReader, learning_rate, m_epoch, n_images, n_input, n_output, dict_Param, forward3, backward3, update3, batch_size)
    SaveResult(dict_Param)
    correct, num_images = Test(dataReader, n_output, dict_Param, n_input, forward3)
    return correct/num_images

if __name__ == '__main__':
    n_output = 10
    dataReader = LoadData(n_output)
    n_images = dataReader.num_example
    n_input = dataReader.num_feature
    dP = InitialParameters3(n_input, 128, 64, n_output, 2)
    correct_rate = []
    learning_rate_list = [0.05, 0.1, 0.2, 0.4, 0.8]
    for i in range(5):
        correct_rate.append(main(learning_rate_list[i], 128, 64, 2, 10, dP))
    plt.figure()
    plt.plot(learning_rate_list, correct_rate)
    plt.xlabel("learning_rate")
    plt.ylabel("correct_rate")
    plt.show()

结果如下图

1614471-20190422180526971-141923190.png

代码连续运行两次得到的结果图相等,说明基本能排除随机初始化带来的干扰(之后经过多次测试发现仍有小概率产出不同的结果图,按理说因为每次随机种子可能不一样所以数值会不一样,但每个点的大小关系应该不会变才对,然而事实上却并非如此,至于原因就不得而知了Orz
接着缩小学习率范围提高精度,得到结果如图

    learning_rate_list = [0.2, 0.3, 0.4, 0.5, 0.6]

1614471-20190422181427947-1976017682.png

    learning_rate_list = [0.2, 0.25, 0.3, 0.35, 0.4]

1614471-20190422181853427-2064093441.png

因此基本可以认定学习率为0.3时,有最佳的结果

- III.调整batch_size

用同样的方式修改代码

if __name__ == '__main__':
    n_output = 10
    dataReader = LoadData(n_output)
    n_images = dataReader.num_example
    n_input = dataReader.num_feature
    dP = InitialParameters3(n_input, 128, 64, n_output, 2)
    correct_rate = []
    batch_size_list = [2, 5, 10, 20, 30]
    for i in range(5):
        correct_rate.append(main(0.3, 128, 64, 2, batch_size_list[i], dP))
    plt.figure()
    plt.plot(batch_size_list, correct_rate)
    plt.xlabel("batch_size")
    plt.ylabel("correct_rate")
    plt.show()

结果如图

1614471-20190422182444165-294040965.png

看起来主要影响力在于梯度下降速度和平滑程度的batch_size在足够大之后并不怎么影响最终结果,所考虑使用20作为batch_size的最终值

- IV.调整max_epoch

代码如下

if __name__ == '__main__':
    n_output = 10
    dataReader = LoadData(n_output)
    n_images = dataReader.num_example
    n_input = dataReader.num_feature
    dP = InitialParameters3(n_input, 128, 64, n_output, 2)
    correct_rate = []
    m_epoch_list = [1, 2, 5, 10, 20, 30]
    for i in range(5):
        correct_rate.append(main(0.3, 128, 64, m_epoch_list[i], 20, dP))
    plt.figure()
    plt.plot(m_epoch_list, correct_rate)
    plt.xlabel("m_epoch")
    plt.ylabel("correct_rate")
    plt.show()

结果如下

1614471-20190422184956011-808772948.png

可以看出随着max_epoch值的增大,准确率随之提升,但是准确率提升的幅度却在下降,因此可以认为当max_epoch取得一个值后,之后再提升所带来的准确率提升效益过低,结合本次实验的结果,可以认为max_epoch取值为20时可以在不影响运行速度的情况下取得最佳的结果

3.最终结果显示

根据上述实验结果得出结论,各个参数在达到以下值时,准确率有最佳的结果

    learning_rate = 0.3
    n_hidden1 = 128
    n_hidden2 = 64
    m_epoch = 20
    batch_size = 20

将这些值带入原代码中运行得到最终的结果
rate=9825 / 10000 = 0.9825
其Loss曲线为

1614471-20190422185445671-197797169.png

转载于:https://www.cnblogs.com/ineffable-sk/p/10751205.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值