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

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()

最高点是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()

结果如下图

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

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

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

因此基本可以认定学习率为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()

结果如图

看起来主要影响力在于梯度下降速度和平滑程度的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()

结果如下

可以看出随着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曲线为

猜你喜欢

转载自www.cnblogs.com/ineffable-sk/p/10751205.html