小波神经网络,二分类,python

发布时间 2023-07-12 20:44:19作者: 奋发图强的小赵

小波神经网络参考博客https://blog.csdn.net/weixin_42051846/article/details/128765295?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168915375016800215081571%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168915375016800215081571&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-128765295-null-null.142^v88^control_2,239^v2^insert_chatgpt&utm_term=%E5%B0%8F%E6%B3%A2%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9Cpython&spm=1018.2226.3001.4187

博客:https://blog.csdn.net/MATLAB_Lover520/article/details/129989258?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522168915787416800226545527%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=168915787416800226545527&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-129989258-null-null.142^v88^control_2,239^v2^insert_chatgpt&utm_term=%E5%B0%8F%E6%B3%A2%E7%A5%9E%E7%BB%8F%E7%BD%91%E7%BB%9C%E6%98%AF%E4%BB%80%E4%B9%88&spm=1018.2226.3001.4187

简书:https://www.jianshu.com/p/c9a30700063e

小波神经网络最主要的特征是它的隐含层神经元激活函数为小波基函数

小波神经网络是将神经网络的激活函数,例如Sigmod函数,替换成小波函数,而相应的输入层到隐层的权值及激活阈值,由小波函数的尺度伸缩因子和时间平移因子所代替

小波神经网络主要有四个参数参与计算,这四个参数分别是小波基函数的平滑因子b伸缩因子a以及隐含层与输出层的两个连接权值,这四个参数值的大小将直接影响网络的性能,平移因子b和伸缩因子a都是通过训练得到的,确定变化量的方法依然是误差反传算法

np.random.uniform() 和 np.random.randint() 是 numpy 库中用于生成随机数的函数,它们的主要区在于生成的随机数的分布和取值范围。

- np.random.uniform() 生成的是服从均匀分布的随机数,即生成的随机数在指定的最小值和最大值之间是等概率分布的。它接受最小值和最大值作为参数,并可以指定生成随机数的数量。

- np.random.randint() 生成的是服从离散均匀分布的随机整数,即生成的随机整数在指定的最小值和最大值之间是等概率分布的。它接受最小值和最大值作为参数,并可以指定生成随机整数的数量。

具体区别如下:

- 参数类型:np.random.uniform() 的参数可以是浮点数,而 np.random.randint() 的参数必须是整数。
- 生成的值类型:np.random.uniform() 生成的是连续的浮点数,而 np.random.randint() 生成的是离散的整数。
- 取值范围:np.random.uniform() 生成的随机数可以取到最小值和最大值,而 np.random.randint() 生成的随机整数只能取到最小值,但不包含最大值。

举个例子,假设要生成一个范围在0到1之间的随机数,可以使用以下代码:

```python
import numpy as np

uniform_num = np.random.uniform(0, 1)
print(uniform_num)
```

输出:

```
0.674735336768
```

如果要生成一个范围在0到9之间的随机整数,可以使用以下代码:

```python
import numpy as np

int_num = np.random.randint(0, 10)
print(int_num)
```

输出:

```
6
```

 代码如下:

#库的导入
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split

#激活函数
def tanh(x):
    return (np.exp(x)-np.exp(-x))/(np.exp(x)+np.exp(-x))
#激活函数偏导数
def de_tanh(x):
    return (1-x**2)
#小波基函数
def wavelet(x):
    return (np.cos(1.75*x)) * (np.exp((x**2)/(-2)))
#小波基函数偏导数
def de_wavelet(x):
    y = (-1) * (1.75 * np.sin(1.75 * x)  + x * np.cos(1.75 * x)) * (np.exp(( x **2)/(-2)))
    return y

#数据的导入
data=pd.read_pickle('ICC_rms.pkl')
df=pd.DataFrame(data)
X = df.iloc[:, 0:510].values #所有样本的x值,0-510列 矩阵(1544,510)由此得出样本个数1544个,特征510
y = df.iloc[:, 511].values #所有样本的标签,511列 矩阵(1544,)
#把y转成1-0形式,Neurons对应0,Astrocytes对应1
Y=np.array([-1.0] * 1544)
for i in range(len(y)):
    if y[i] =='Neurons':
        Y[i]=0
    if y[i] =='Astrocytes':
        Y[i]=1
# y=['Neurons' 'Neurons' 'Neurons' ... 'Astrocytes' 'Astrocytes' 'Astrocytes']
# Y=[0. 0. 0. ... 1. 1. 1.]

# x为输入层神经元个数,y为隐层神经元个数,z输出层神经元个数
# 创建的是参数初始化函数,参数有各层间的权重weight和阈值即偏置value就是b
# 本例的x,y=len(dataset[0])=22,z=1
def parameter_initialization(x, y, z):
    # 隐层阈值
    value1 = np.random.randint(-5, 5, (1, y)).astype(np.float64)  # 随机生成(-5,5)之间的整数组成(1,y)的数组,然后再将其转为浮点数显示

    # 输出层阈值
    value2 = np.random.randint(-5, 5, (1, z)).astype(np.float64)

    # 输入层与隐层的连接权重
    weight1 = np.random.randint(-5, 5, (x, y)).astype(np.float64)

    # 隐层与输出层的连接权重
    weight2 = np.random.randint(-5, 5, (y, z)).astype(np.float64)

    #平移因子b和伸缩因子a
    h_b = np.random.uniform(low=-x, high=x, size=[y, 1])
    h_a = np.random.uniform(low=-x, high=x, size=[y, 1])

    return weight1, weight2, value1, value2,h_a,h_b

# 创建训练样本的函数,返回训练完成后的参数weight和value,这里的函数是经过一次迭代后的参数,即所有的样本经过一次训练后的参数
# 具体参数的值可以通过设置迭代次数和允许误差来进行确定
def trainning(dataset, labelset, weight1, weight2, value1, value2,h_a,h_b,y):
    # x为步长
    x = 0.01  # 学习率
    for i in range(len(dataset)):  # 依次读取数据特征集中的元素,一个元素即为一个样本所含有的所有特征数据

        # 输入数据
        # (1,21)
        inputset = np.mat(dataset[i]).astype(np.float64)  # 每次输入一个样本,将样本的特征转化为矩阵,以浮点数显示

        # 数据标签
        # (1,1)
        outputset = np.mat(labelset[i]).astype(np.float64)  # 输入样本所对应的标签

        # 隐层输入,隐层的输入是由输入层的权重决定的,wx
        # input1:(1,21).(21,21)=(1,21)
        input1 = np.dot(inputset, weight1).astype(np.float64)

        #隐含层的输入到输出计算(小波函数和其两个因子起作用的地方)
        outputwavelet=wavelet((input1-h_b)/h_a).astype(np.float64)

        # 隐层输出,由隐层的输入和阈值以及激活函数决定的,这里的阈值也可以放在输入进行计算
        # sigmoid((1,21)-(1,21))=(1,21)
        output2 = tanh(outputwavelet - value1).astype(np.float64)

        # 输出层输入,由隐层的输出
        # (1,21).(21,1)=(1,1)
        input2 = np.dot(output2, weight2).astype(np.float64)

        # 输出层输出,由输出层的输入和阈值以及激活函数决定的,这里的阈值也可以放在输出层输入进行计算
        # (1,1).(1,1)=(1,1)
        output3 = tanh(input2 - value2).astype(np.float64)
        err = outputset - output3
        belta = de_tanh(output3).transpose()

        for j in range(y):
            sum1 = 0.0
            sum2 = 0.0
            sum3 = 0.0
            sum4 = 0.0
            sum5 = 0.0
            for m in range(len(dataset)):
                sum1 += err[m, :] * belta[m, :] * weight2[j, :] * de_wavelet(outputwavelet[m, j]) * (input1[m, :] / h_a[j, :])
                # 1*1
                sum2 += err[m, :] * belta[m, :] * weight2[j, :] * de_wavelet(outputwavelet[m, j]) * (-1) * (1 / h_a[j, :])
                # 1*1
                sum3 += err[m, :] * belta[m, :] * weight2[j, :] * de_wavelet(outputwavelet[m, j]) * (-1) * (
                            (input1[m, :] * weight1[j, :].T - h_b[j, :]) / (h_a[j, :] * h_a[j, :]))
                # 1*1
                sum4 += err[m, :] * belta[m, :] * output2[m, j]
            delta_w1 = sum1
            delta_b = sum2
            delta_a = sum3
            delta_w2 = sum4
            # 根据误差项对四个参数进行更新
            weight1[j, :] = weight1[j, :] + x * delta_w1
            h_b[j, :] = h_b[j, :] + x * delta_b
            h_a[j, :] = h_a[j, :] + x * delta_a
            weight2[j, :] = weight2[j, :] + x * delta_w2


        # # 更新公式由矩阵运算表示
        # # a:(1,1)
        # a = np.multiply(output3, 1 - output3)  # 输出层激活函数求导后的式子,multiply对应元素相乘,dot矩阵运算
        # # g:(1,1)
        # g = np.multiply(a, outputset - output3)  # outputset - output3:实际标签和预测标签差
        # # weight2:(21,1),np.transpose(weight2):(1,21),b:(1,21)
        # b = np.dot(g, np.transpose(weight2))
        # # (1,21)
        # c = np.multiply(output2, 1 - output2)  # 隐层输出激活函数求导后的式子,multiply对应元素相乘,dot矩阵运算
        # # (1,21)
        # e = np.multiply(b, c)
        #
        # f=np.divide()
        #
        # value1_change = -x * e  # (1,21)
        # value2_change = -x * g  # (1,1)
        # weight1_change = x * np.dot(np.transpose(inputset), e)  # (21,21)
        # weight2_change = x * np.dot(np.transpose(output2), g)  # (21,1)
        #
        # # 更新参数,权重与阈值的迭代公式
        # value1 += value1_change
        # value2 += value2_change
        # weight1 += weight1_change
        # weight2 += weight2_change
    return weight1, weight2, value1, value2,h_a,h_b

def testing(dataset1, labelset1, weight1, weight2, value1, value2):
    # 记录预测正确的个数
    rightcount = 0
    for i in range(len(dataset1)):
        # 计算每一个样例的标签通过上面创建的神经网络模型后的预测值
        inputset = np.mat(dataset1[i]).astype(np.float64)
        outputset = np.mat(labelset1[i]).astype(np.float64)
        output2 = tanh(np.dot(inputset, weight1) - value1)
        output3 = tanh(np.dot(output2, weight2) - value2)

        # 确定其预测标签
        if output3 > 0.5:
            flag = 1
        else:
            flag = 0
        if labelset1[i] == flag:
            rightcount += 1
        # 输出预测结果
        #print("预测为%d   实际为%d" % (flag, labelset1[i]))
    # 返回正确率
    return rightcount / len(dataset1)

def main():
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.20, random_state=0)
    weight1, weight2, value1, value2,h_a,h_b = parameter_initialization(len(X_train[0]), len(X_train[0]), 1)
    for i in range(10):
        # 获得对所有训练样本训练迭代一次后的待估参数
        weight1, weight2, value1, value2,h_a,h_b = trainning(X_train, Y_train, weight1, weight2, value1, value2,h_a,h_b,len(X_train[0]))
        print("epoch:%d/10",i+1)
    # 对测试样本进行测试,并且得到正确率
    rate = testing(X_test, Y_test, weight1, weight2, value1, value2)
    print("正确率为%f" % (rate))

if __name__ == '__main__':
    main()

代码报错:numpy.linalg.LinAlgError: Last 2 dimensions of the array must be square

考虑把激活函数tanh换成sigmoid算了