卷积神经网络一般用来处理图像信息,对于序列这种一维的数据而言,我们就得采用一维的卷积,tensorflow中提供有专用的函数conv1d,各参数的使用说明如下:
conv1d参数 | 说明 |
---|---|
value | 输入数据,value的格式为:[batch, in_width, in_channels],batch为样本维,表示多少个样本,in_width为宽度维,表示样本的宽度,in_channels维通道维,表示样本有多少个通道。 |
filters | 卷积核,filters的格式为:[filter_width, in_channels, out_channels]。按照value的第二种看法,filter_width可以看作每次与value进行卷积的行数,in_channels表示value一共有多少列(与value中的in_channels相对应)。out_channels表示输出通道,可以理解为一共有多少个卷积核,即卷积核的数目。 |
stride | 步长,一个整数,表示每次(向下)移动的距离(TensorFlow中解释是向右移动的距离,这里可以看作向下移动的距离)。 |
padding | 同conv2d,value是否需要在下方填补0。 |
name | 名称。可省略。 |
其实,它和二维卷积很相似。下面是一个一维卷积的程,我定义的网络由3个卷积层和2个全连接层组成:
#2022.3.10
#读取csv文件,并保存为ndarry类型
#读取的数据是一个矩阵,每一行都是一个样本
from cgi import test
import csv
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
M_Input = 20 #输入变量为20个欠采样点
M_Output = 2 #输出变量数的两个Dirac脉冲的时延
## 采用np.load读取CSV文件
csv_data = np.loadtxt(open("D:/FRIsignal.csv","rb"),delimiter=",",skiprows=0)#返回的数据为ndarry
print('csv文件导入成功!')
data_shape = csv_data.shape #返回数据的维度
data_dim = csv_data.ndim #ndarry的秩
[m, n] = data_shape # 返回数据的行数和列数
print("cav_data.dim = ",data_dim)
print("cav_data.shape = ",data_shape)
print("cav_data m ={0}, cav_data m ={1}".format(m, n))
## 分别给输出数据及标签赋值
X_train = csv_data[0:7500,0:M_Input]#取第0,1,...,(M_Input-1)数据,注意ndarry是从0开始索引的
Y_train = csv_data[0:7500,M_Input:M_Input+M_Output]#取最后两列数据
X_test = csv_data[7500:10000,0:M_Input]#取第0,1,...,(M_Input-1)数据,注意ndarry是从0开始索引的
Y_test = csv_data[7500:10000,M_Input:M_Input+M_Output]#取最后两列数据
print('X_train.shape = ',X_train.shape)#显示X_trian的维度
print('Y_train.shape = ',Y_train.shape)#显示Y_train的维度
#print('X_train[0] = ',X_train[5])#打印出来查看是否正确读入
print('X_train.dtype = ',X_train.dtype)#打印出来查看是否正确读入
print('X_test.shape = ',X_test.shape)
print('Y_test.shape = ',Y_test.shape)#显示Y_train的维度
#定义归一化函数,经过我实际验证,发现经过归一化之后反而不好
def normalize(X):
mean = np.mean(X) #均值
std = np.std(X) #默认计算每一列的标准差
X = (X - mean)/std
return X
#X_train = normalize(X_train) #对输入变量按列进行归一化
print('X_train[0] = ',X_train[5])#随便打印出来某一个样本,查看归一化的效果
##显示某一个样本
#==============================网络参数=====================================================
#parameters超参数
learning_rate = 0.09 #学习率
training_iters = 1000 #训练次数
batch_size = 10 #批训练样本大小
display_step = 10 #打印训练结果的Iter的步长
#Network Parameters
n_input = 20 #输入层节点数
n_output = 2 #输出层节点数
#==========================================================================================
#为训练数据申明占位符
x = tf.placeholder(tf.float32,[None, n_input])
y = tf.placeholder(tf.float32,[None, n_output])
#定义卷积层
#定义一个输入为x,权值为w,偏置为b,给定步幅的卷积层,激活函数是ReLu,padding设为SAMEM模式,strids为1,表示步幅为1
def conv1d(x, w, b, stride=1):
x = tf.nn.conv1d(x, w, stride = stride,
padding = 'SAME')
x = tf.nn.bias_add(x,b)
return tf.nn.relu(x) #卷积层连接的是relu激活函数
#定义一个输入是x的maxpool层,卷积核为ksize并且padding为SAME
def maxpool2d(x, k=2):
return tf.nn.max_pool(x, ksize = [1, k, k, 1],strides = [1, k, k, 1],
padding = 'SAME')
#定义神经网络,其构成是两个全连接的隐藏层,最后是输出层
def conv_net(x, weights, biases):
#reshape the input picture
x = tf.reshape(x, shape = [-1, n_input, 1])#将输入数据变为3-D张量,一维卷积操作时经常采用3-D张量的形式
#First convolution layer
conv1 = conv1d(x, weights['wc1'], biases['bc1'])
#Second convolution layer
conv2 = conv1d(conv1, weights['wc2'], biases['bc2'])
#Third convolution layer
conv3 = conv1d(conv2, weights['wc3'], biases['bc3'])
fc1 = tf.reshape(conv3, [-1, #进入到全连接层之前需要由4-D张量变为矩阵
weights['wd1'].get_shape().as_list()[0]])
#Fully connected layer1
fc1 = tf.add(tf.matmul(fc1, weights['wd1']),biases['bd1'])
fc1 = tf.nn.relu(fc1) #relu激活函数,看到有篇论文的全连接层自编码器也都是采用的relu激活函数
#Fully connected layer2
fc2 = tf.add(tf.matmul(fc1, weights['wd2']),biases['bd2'])
fc2 = tf.nn.relu(fc2)
#output the class prediction
out = tf.add(tf.matmul(fc2,weights['out']),biases['out'])
return out
#定义网络层的权重和偏置全连接层有1024个输入和10个输出对应于最后
#的数字数目。所有的权重和偏置用randon_normal分布完成初始化:
weights = {
# conv connected , 卷积核大小为3*1,100个特征图输出
'wc1':tf.Variable(tf.random_normal([3, 1, 100])),
# conv connected , 卷积核大小为3*1,100个特征图输入,100个特征图输出
'wc2':tf.Variable(tf.random_normal([3, 100, 100])),
# conv connected , 卷积核大小为3*1,100个特征图输入,100个特征图输出
'wc3':tf.Variable(tf.random_normal([3, 100, 100])),
# fully connected, 20 inputs, and 15 outputs
'wd1':tf.Variable(tf.random_normal([20*100, 100])),
'wd2':tf.Variable(tf.random_normal([100, 100])),
# 15 inputs, 10 outputs for class digits
'out':tf.Variable(tf.random_normal([100,2]))
}
biases = {
'bc1':tf.Variable(tf.random_normal([100])), #100个特征图
'bc2':tf.Variable(tf.random_normal([100])), #100个特征图
'bc3':tf.Variable(tf.random_normal([100])), #100个特征图
'bd1':tf.Variable(tf.random_normal([100])),
'bd2':tf.Variable(tf.random_normal([100])),
'out':tf.Variable(tf.random_normal([2]))
}
#建立一个给定权重和偏置的convnet。定义均方根误差的损失函数,并用Adam优化器进行损失最小化。
#优化后,计算精度:
pred = conv_net(x, weights, biases)
cost = tf.reduce_mean(tf.square(y - pred))#损失函数,均方误差
optimizer = tf.train.AdamOptimizer(learning_rate = learning_rate).minimize(cost)
init_op = tf.global_variables_initializer()
#启动计算图,并迭代train_iterats次,其中每次输入batch_size个数据进行优化,请注意,用从mnist数据集分离出的
#mnist.train数据进行训练,每进行display_step次迭代,会计算当前的精度,最后,在2048个测试图片上计算精度,
#此时无dropout
total = []#定义一个空列表,用于存储每一次Epoch的误差
with tf.Session() as sess:
sess.run(init_op)#初始化变量
for i in range(training_iters):
_, l = sess.run([optimizer, cost],feed_dict = {x:X_train, y:Y_train})
total.append(l)
print('Epoch {0}: Loss {1}'.format(i, l))
test_cost = sess.run(cost, feed_dict = {x: X_test, y:Y_test})
#绘制损失函数
plt.figure(num=1)
plt.title('loss curve')
plt.xlabel('Epoch', color = 'red')
plt.ylabel('loss', color = 'blue')
plt.plot(total)
plt.show()
print('test cost is : {0}'.format(test_cost))