《深度学习的数学》(https://www.ituring.com.cn/book/2593)第三章实例“用EXCEL体验神经网络”——python实现

所使用的的数据连接:https://www.ituring.com.cn/book/download/d16bf588-375b-4176-b319-ec3c3a2d99a1
原书网址

读入EXCEL文件的DATA工作簿中的学习数据

将读入的数据分解成为 12*64 维数组,每一行代表一个待识别的数字(0或者 1)
将正解转换为tuple形式并保存在value列表中。其中(0,1)代表1, (1,0)代表0
这一步比较复杂,要反复尝试。

import pandas, numpy
file = r'D:\ChromeCoreDownloads\【Excel示例文件】深度学习的数学\3-5 NN(求解器).xlsx'
data = pandas.read_excel(file, sheet_name='Data', engine='openpyxl')
df = pandas.DataFrame(data)
# 通过切片,去除部分没有意义的行和列
df1 = df.iloc[2:8, 10:]

file的文件路径要更改为相应的文件路径。

value = []
for i in range(0, 256, 4):
    target_area = df1.iloc[:, i:i+4]
    if int(target_area.iloc[5, 3]) == 0:
        value.append((1, 0))
    elif int(target_area.iloc[5, 3]) == 1:
        value.append((0, 1))
    else:
        print('error', df1.iloc[0, 0])
    target_area = target_area.iloc[1:-1, 0:3]
    # 将4行3列的学习数据转化为1行
    target_area = numpy.array(target_area).flatten()
    target_area = pandas.DataFrame(target_area).transpose()
    if i == 0:
        data_new = target_area
    else:
        # 将学习数据打包为一个Dataframe
        data_new.loc[len(data_new)] = target_area.iloc[0, :]

print(data_new)
print(value)

结果如下图:

      0    1    2    3    4    5    6    7    8    9   10   11
0   1.0  1.0  1.0  1.0  0.0  1.0  1.0  0.0  1.0  1.0  1.0  1.0
1   0.0  1.0  1.0  1.0  0.0  1.0  1.0  0.0  1.0  1.0  1.0  1.0
2   1.0  1.0  0.0  1.0  0.0  1.0  1.0  0.0  1.0  1.0  1.0  1.0
3   1.0  1.0  1.0  1.0  0.0  1.0  1.0  0.0  1.0  1.0  1.0  0.0
4   1.0  1.0  1.0  1.0  0.0  1.0  1.0  0.0  1.0  0.0  1.0  1.0
..  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...  ...
59  0.0  0.0  0.0  0.0  1.0  0.0  0.0  1.0  0.0  1.0  1.0  0.0
60  0.0  0.0  0.0  0.0  1.0  0.0  0.0  1.0  0.0  0.0  1.0  0.0
61  0.0  1.0  0.0  0.0  1.0  0.0  0.0  1.0  0.0  0.0  0.0  0.0
62  0.0  1.0  0.0  0.0  0.0  1.0  0.0  0.0  1.0  0.0  1.0  0.0
63  0.0  1.0  0.0  1.0  0.0  0.0  1.0  0.0  0.0  0.0  1.0  0.0

[64 rows x 12 columns]
[(1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (1, 0), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1)]

Process finished with exit code 0

以下是三层模型的计算过程, 由于没有找到类似EXCEL的规划求解简便办法,我希望通过改变seed(i)的i值,改变参数(w1, w2,w2, b1, b2, b3等,即权重和偏置)。通过循环,选取当代价函数C(c(k)=1/2(t1-a1)**2 + (t2-a2)**2平方误差相加乘以1/2)取最小值时seed(i)的i值,并将seed(i)确定时的固定的“随机的”参数值作为模型的参数。

# 定义两个列表保存数据
c_list = []
index_list = []

def example(data_new, i):
    # 通过改变seed来获得不同的代价函数C的值
    # 获取隐藏层的初始值, (w21, w22, w23)对应隐藏层的权重,b21, b22, b23对应隐藏层的偏置。
    numpy.random.seed(i)
    data_new = numpy.array(data_new)
    w21 = numpy.random.randn(3, 12)[0]
    w22 = numpy.random.randn(3, 12)[1]
    w23 = numpy.random.randn(3, 12)[2]
    b21, b22, b23 = numpy.random.randn(3)
    # print(w21, b21)
    # 计算隐藏层的各个神经元输入z及输出a。
    z21 = data_new.dot(w21) + b21
    a21 = 1/(numpy.exp(-1*z21)+1)
    z22 = data_new.dot(w22) + b22
    a22 = 1/(numpy.exp(-1*z22)+1)
    z23 = data_new.dot(w23) + b23
    a23 = 1/(numpy.exp(-1*z23)+1)
    # print(z21)
    # 获取输出层初始化参数值(权重和偏置)
    w31 = numpy.random.randn(2, 3)[0]
    w32 = numpy.random.randn(2, 3)[1]
    b31, b32 = numpy.random.randn(2)
    # print(w31, b31)
    # 计算输出层的输入z及输出a
    z31 = numpy.array([a21, a22, a23]).transpose().dot(numpy.array(w31)) + b31
    z32 = numpy.array([a21, a22, a23]).transpose().dot(numpy.array(w32)) + b32
    a31 = 1/(numpy.exp(-1*z31)+1)
    a32 = 1/(numpy.exp(-1*z32)+1)
    # print(len(a31))
    # print(a31, a32)
    # 计算代价函数值c
    c = 0
    # print(i)
    for j in range(64):
        c += 1/2 * ((a31[j]-value[j][0])**2 + (a32[j]-value[j][1])**2)
    # print(c)
    # c_list.append(c)
    return c, i
def test():
    # c 值初始化为了避免报错
    c = 100
    for i in range(100):
        try:
            c, i = example(data_new, i)
        except ValueError:
            print(1)
            pass
        if c < 20:
            c_list.append(c)
            index_list.append((c, i))
            if c < 5:
                break
    a = pandas.Series(c_list)
    b = a.min()
    print(b, c_list.index(b))
    print(index_list[c_list.index(b)])
# 计算最佳的i值,使代价函数c值最小
test()

用书中的例子测试, seed(i)当i取0时, 参数(w1, w2,w2, b1, b2, b3等,即权重和偏置)取值一定。计算结果为(0.9675370110460244 0.33980584171583866), 与理想的输出结果(1,0), 代表‘0’,比较接近,可以实现准确的预测。当i取86是c为12.188238799263141。

def test_example(data_new, i):
    # 计算结果
    # 获取隐藏层的初始值, (w21, w22, w23)对应隐藏层
    numpy.random.seed(i)
    data_new = numpy.array(data_new)
    w21 = numpy.random.randn(3, 12)[0]
    w22 = numpy.random.randn(3, 12)[1]
    w23 = numpy.random.randn(3, 12)[2]
    b21, b22, b23 = numpy.random.randn(3)
    # 计算隐藏层的z及输出a
    z21 = data_new.dot(w21) + b21
    a21 = 1 / (numpy.exp(-1 * z21)+1)
    z22 = data_new.dot(w22) + b22
    a22 = 1 / (numpy.exp(-1 * z22)+1)
    z23 = data_new.dot(w23) + b23
    a23 = 1 / (numpy.exp(-1 * z23)+1)
    # 获取输出层初始化值
    w31 = numpy.random.randn(2, 3)[0]
    w32 = numpy.random.randn(2, 3)[1]
    b31, b32 = numpy.random.randn(2)
    # 计算输出层的z及输出a
    z31 = numpy.array([a21, a22, a23]).transpose().dot(numpy.array(w31)) + b31
    z32 = numpy.array([a21, a22, a23]).transpose().dot(numpy.array(w32)) + b32
    a31 = 1 / (numpy.exp(-1 * z31)+1)
    a32 = 1 / (numpy.exp(-1 * z32)+1)
    if a31 > a32:
        print('结果为', 0)
    elif a31 < a32:
        print('结果为', 1)
    print(a31, a32)

# 用书中的例子测试结果
data_test = (0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0)
test_example(data_test, 86)
# 计算结果如下
0.44316388139613166 0.35893481560523993
结果为 0

期间还参考了很多博主的文件,一并感谢。
以上只是我的粗陋见解,特别是求最优化参数的方法,应该还有很大的改进空间,希望路过的多多指教。

你可能感兴趣的:(python,矩阵,神经网络,python,深度学习)