O’Shea基于深度学习调制识别代码

Convolutional Radio Modulation Recognition Networks 论文代码复现

1. 数据集下载

数据集生成源代码(需要GNU Radio来实现,如需安装学习参考主页相关教程)
链接: https://github.com/radioML/dataset
现成的数据集下载(来自DeepSig公司主页)
链接: https://www.deepsig.ai/datasets
一般来说,RADIOML 2016.10A就可以满足需求,其他数据集将消耗更大的硬件需求。

2. 原论文

链接: https://arxiv.org/abs/1602.04105
O’Shea基于深度学习调制识别代码_第1张图片

3. 软硬件约束

1.tensorflow2,keras2
2.gpu:RTX3080Ti,cpu:Intel Xeon E5-2690 v4

4. 代码

(1)导包,本来我是tf2,后来为了适应tf1版本,加了几行代码,现在tf1应该可以用。

from tensorflow.compat.v1 import ConfigProto
from tensorflow.compat.v1 import InteractiveSession

config = ConfigProto()
config.gpu_options.allow_growth = True
session = InteractiveSession(config=config)

import h5py
import numpy as np
#import theano as th
import os,random
import pickle,random, sys
import tensorflow as tf
tf.compat.v1.enable_eager_execution()
from tensorflow import keras
import matplotlib.pyplot as plt
import gc
from tensorflow.keras.layers import Reshape,Dense,Dropout,Activation,Flatten,Convolution2D, MaxPooling2D, ZeroPadding2D,LSTM


%matplotlib inline
#os.environ["KERAS_BACKEND"] = "tensorflow"
os.environ["THEANO_FLAGS"]  = "device=gpu%d"%(0)

(2)导入数据集,X是数据,lbl是标签(包含调制类型和信噪比)

Xd = pickle.load(open("RML2016.10a_dict.pkl",'rb'),encoding='latin1')
#data=pk.load(f,encoding='latin1')
#print(data)
snrs,mods = map(lambda j: sorted(list(set(map(lambda x: x[j], Xd.keys())))), [1,0])
X = []  
lbl = []
for mod in mods:
    for snr in snrs:
        X.append(Xd[(mod,snr)])
        for i in range(Xd[(mod,snr)].shape[0]):  lbl.append((mod,snr))
X = np.vstack(X)

(3)划分训练集和数据集,to_onehot打标签

np.random.seed(2016)
n_examples = X.shape[0]
n_train = int(n_examples*0.8)
train_idx = np.random.choice(range(0,n_examples), size=n_train, replace=False)
test_idx = list(set(range(0,n_examples))-set(train_idx))
X_train = X[train_idx]
X_test =  X[test_idx]
def to_onehot(yy):
    yy1 = np.zeros([len(yy), max(yy)+1])
    yy1[np.arange(len(yy)),yy] = 1
    return yy1
Y_train = to_onehot(list(map(lambda x: mods.index(lbl[x][0]), train_idx)))
Y_test = to_onehot(list(map(lambda x: mods.index(lbl[x][0]), test_idx)))

in_shp = list(X_train.shape[1:])
print (X_train.shape, in_shp)

classes = mods
print('数据集总数:',n_examples)
print('调制方式' , len(mods),'种:' ,mods)
print('信噪比:',snrs)

(4)神经网络结构

dr = 0.5 # dropout rate (%)
lstm_output_size=512
model = keras.Sequential()
model.add(Reshape(in_shp+[1], input_shape=in_shp))
model.add(ZeroPadding2D(padding=(0,2)))
model.add(Convolution2D(256, (1,3),  padding='valid', activation="relu", name="conv1"))
model.add(Dropout(dr))
model.add(ZeroPadding2D(padding=(0, 2)))
model.add(Convolution2D(80, (2, 3), padding="valid", activation="relu", name="conv2"))
model.add(Dropout(dr))
model.add(Flatten())
model.add(Dense(1024, activation='relu', name="dense1"))
model.add(Dense(256, activation='relu', name="dense1"))
model.add(Dropout(dr))
model.add(Dense( len(classes), name="dense2" ))
model.add(Activation('softmax'))
model.add(Reshape([len(classes)]))
model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=["accuracy"])

model.summary()

(5)训练,引入了早停法

# Set up some params 
epochs = 100     # number of epochs to train on
batch_size = 1024  # training batch size
#   - call the main training loop in keras for our network+dataset
filepath = 'conv.h5'
history = model.fit(X_train,
    Y_train,
    batch_size=batch_size,
    epochs=epochs,
    verbose=2,
    validation_data=(X_test, Y_test),
    callbacks = [
        keras.callbacks.ModelCheckpoint(filepath, monitor='val_loss', verbose=0, save_best_only=True, mode='auto'),
        keras.callbacks.EarlyStopping(monitor='val_loss', patience=5, verbose=0, mode='auto')
    ])
# we re-load the best weights once training is finished
model.load_weights(filepath)

(6)记录并绘制损失曲线

score = model.evaluate(X_test, Y_test, batch_size=batch_size,verbose=0)
print (score)
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
plt.subplot(1, 2, 1)
plt.plot(acc, label='Training Accuracy')
plt.plot(val_acc, label='Validation Accuracy')
plt.title('Training and Validation Accuracy')
plt.legend()

plt.subplot(1, 2, 2)
plt.plot(loss, label='Training Loss')
plt.plot(val_loss, label='Validation Loss')
plt.title('Training and Validation Loss')
plt.legend()
plt.show()

(7)绘制混淆矩阵

def plot_confusion_matrix(cm, title='Confusion matrix', cmap=plt.cm.Blues, labels=[]):
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(labels))
    plt.xticks(tick_marks, labels, rotation=45)
    plt.yticks(tick_marks, labels)
    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label'
# Plot confusion matrix
test_Y_hat = model.predict(X_test, batch_size=batch_size)
conf = np.zeros([len(classes),len(classes)])
confnorm = np.zeros([len(classes),len(classes)])
for i in range(0,X_test.shape[0]):
    j = list(Y_test[i,:]).index(1)
    k = int(np.argmax(test_Y_hat[i,:]))
    conf[j,k] = conf[j,k] + 1
for i in range(0,len(classes)):
    confnorm[i,:] = conf[i,:] / np.sum(conf[i,:])
plot_confusion_matrix(confnorm, labels=classes)


# Plot confusion matrix
acc = {}
for snr in snrs:

    # extract classes @ SNR
    test_SNRs = list(map(lambda x: lbl[x][1], test_idx))#map在tensorflow2中前面要加list
    test_X_i = X_test[np.where(np.array(test_SNRs)==snr)]
    test_Y_i = Y_test[np.where(np.array(test_SNRs)==snr)]    
    # estimate classes
    test_Y_i_hat = model.predict(test_X_i)
    conf = np.zeros([len(classes),len(classes)])
    confnorm = np.zeros([len(classes),len(classes)])
    for i in range(0,test_X_i.shape[0]):
        j = list(test_Y_i[i,:]).index(1)
        k = int(np.argmax(test_Y_i_hat[i,:]))
        conf[j,k] = conf[j,k] + 1
    for i in range(0,len(classes)):
        confnorm[i,:] = conf[i,:] / np.sum(conf[i,:])
    plt.figure()
    plot_confusion_matrix(confnorm, labels=classes, title="ConvNet Confusion Matrix (SNR=%d)"%(snr))
    
    cor = np.sum(np.diag(conf))
    ncor = np.sum(conf) - cor
    print ("Overall Accuracy: ", cor / (cor+ncor))
    acc[snr] = 1.0*cor/(cor+ncor)

(8)绘制信噪比曲线

# Save results to a pickle file for plotting later
print (acc)
fd = open('results_cnn.dat','wb')
pickle.dump( ("CNN2", 0.5, acc) , fd )
# Plot accuracy curve
plt.plot(snrs, list(map(lambda x: acc[x], snrs)))
plt.xlabel('Signal to Noise Ratio')
plt.ylabel('Classification Accuracy')
plt.title("CNN2 Classification Accuracy on RadioML 2016.10 Alpha")

更多调制识别论文的复现论文将陆陆续续发布!

你可能感兴趣的:(深度学习,tensorflow,人工智能)