幅度分布-分类器(无线信道模型)(原创)

 

 

幅度分布-分类器(无线信道模型)

遇到问题:

1,瑞丽信道和莱斯信道重合度较高

2,对数正态信道的波形失真严重

 

一,平坦分布(经检验正确)

方法一:理论合成

mean = np.random.uniform(0.5, 2, 1)

data = np.random.normal(mean, 0.001, sampleNo)

 

 

 

二,瑞利分布(三种方法任选其一即可)

# 方法一:理论合成

delta = 2

data0 = np.random.normal(0, delta, 20000)

data1 = np.random.normal(0, delta, 20000)

data = (data0**2+data1**2)**0.5

 

 

 

方法二:反函数构建

data0 = np.random.random(20000)

data = 2 * np.sqrt(-2 * np.log(data0))

 

 

 

方法三:numpy自带库

scale = np.random.normal(loc=0.0, scale=20)

d0 = np.random.rayleigh(abs(scale), 40000)

 

 

 

三,莱斯分布

方法一:理论合成(经确认,这个理论是正确的)

data0 = np.random.normal(loc=0.0, scale=1, size=length)

data1 = np.random.normal(loc=0.0, scale=1, size=length)

data = np.sqrt((data0 + a) ** 2 + data1 ** 2)

 

 

 

方法二:反函数(这个方法问题很大)(经检验这个是属于对数正态分布的推导)

data0 = np.random.normal(loc=0.0, scale=abs(delta), size=length)

data = np.exp(u + delta * data0)

 

 

 

四,对数正态分布

方法一:理论合成(与瑞利信道的反函数雷同!!!)(经检验完全正确)

data1 = np.random.normal(0, 1, sampleNo )

data = np.exp(u+delta*data1)

 

 

 

方法二:公式法(和理想差距较大,原因:数据量没有达到一定程度。舍弃)

for i in range(len(x)):

    if Y[i] <= lognormal(x[i],u,delta):

        data.append(x[i])

 

 

 

方法三:numpy自带库numpy自带库和理论合成效果相同)

d0 = np.random.lognormal(mean, sigma, 40000)

 

 

 

五,Suzuki分布(确认正确)

方法一:理论合成

data0 = np.random.normal(0, 1, sampleNo)

data1 = np.random.normal(0, 1, sampleNo)

data3 = np.random.normal(0, 1, sampleNo)

u = np.sqrt(data0**2+data1**2)

v = np.exp(m+s*data3)

data = u*v

 

 

 

六,引入数据预处理

 

均值:一阶中心矩

方差:二阶中心矩

中位数:数值从大到小(或者反序)最中间的数值

众数:出现频次最高的数值(这两个数据需要额外处理)

偏度:统计数据分布非对称程度的数字特征

峰度:表征概率密度分布曲线在平均值处峰值高低的特征数

平均绝对误差:所有单个观测值与算术平均值的偏差的绝对值的平均

 

与此同时遇到了一个新的问题:

这些数据处理方法使用原始数据还是统计数据

个人更倾向于统计数据,因为原始数据太过庞大并且数据格式不固定得出来的样值不具有代表性(打脸,统计数据无法使用)

 

统计数据无法使用的原因:因为上面的数据预处理本身就是一个统计的过程,如果使用统计数据那就相当于 原始数据→统计1→统计2,统计两次!

原始数据的改进:1,样本量的减小(但是分布函数依旧);2,将原始数据的预处理数据进行打包减少数据量;3,数据格式直接使用全局的统计即可(这个有可能会出现问题)

 

 

实际计算过程中的错误:众数无法使用;原因:这个是float64精度的几乎没有相等的两个数值

数据预处理:(列为样本序号,横轴依次为均值、标准差、中位数、偏度、峰度、平均绝对误差)

 

 

原始数据标签:(列为样本序号,横轴依次为平坦分布、瑞利分布、莱斯分布、对数正态分布、suzuki分布)

 

 

七,分类器设计

 

由之前做FashionAI的服饰标签属性时设计的CNN训练模型,现在直接拿来改版一下当幅度分布分类器的训练模型(改成DNN网络即可)

 

1,DNN结构

 

# local1 全连接层 1     [6,128]

# local2 全连接层 2     [128,512]

# local3 全连接层 3     [512,128]

# softmax 全连接层 4    [128,5]

 

BATCH_SIZE = 256

CAPACITY = 128

learn_rate = 0.0010485759

step_damp = 100

rate_damp = 0.9

MAX_STEP = 160000

 

2,训练效果

 

 

 

通过上图可知正确率在91%左右,其中为什么不能达到100%的原因,这个是因为:

莱斯分布在主径分量接近零的时候会退化瑞利分布

suzuki分布和对数正态的相似性较大;

 

模拟数据验证1:(Batch_size=64

 

 

模拟数据验证2:(Batch_size=1024

 

 

 

3,实测数据检验

 

 

八,总结

其实这个 幅度分布-分类器 更难设计

难点:

①这个是对个分布函数的随机数数据

②处理数据比较麻烦,直接把随机数的输出输入分类器效果基本为0,这个思路问题很大,并且计算量还大

③统计数据后进行数据预处理,在这里也出现了相关的问题,比如上文说的统计两次的错误

④分类器模型设计,之前都是使用图像处理的卷积网络,由于惯性的缘故。刚开始也想使用一维卷积网络,但是效果一般

 

附录代码:input.pyw

  1 # coding=utf-8
  2 # coded by Mufasa 2018.12.10
  3 # 数据生成程序
  4 # 程序说明:整个体系的数据来源 version3.1
  5 #
  6 """
  7 改进:
  8 ① 将所有的数据进行,再次的验证,舍弃不合理的,提取正确的数据
  9 ② 将与处理数据引入,例如:均值、方差、中位数、众数、峰度、偏度、平均绝对误差
 10 ③ 数据打包测试完成
 11 输出:
 12 d1_batch                [BATCH_SIZE,6]
 13 np.array(d2_batch)      [BATCH_SIZE]
 14 """
 15 
 16 import numpy as np
 17 
 18 
 19 class data_deal:
 20     def d_mean(self, data):  # 均值
 21         return np.mean(data)
 22 
 23     def d_var(self, data):  # 方差
 24         return np.var(data)
 25 
 26     def d_med(self, data):  # 中位数
 27         return np.median(data)
 28 
 29     def d_mod(self, data):  # 众数
 30         counts = np.bincount(data)
 31         return np.argmax(counts)
 32 
 33     def d_kur(self, data):  # 峰度
 34         n = len(data)
 35         mean = np.mean(data)
 36         sigma = np.var(data)
 37         niu4_u = sum((data - mean) ** 4) / n
 38         return niu4_u / (sigma ** 2) - 3
 39 
 40     def d_par(self, data):  # 偏度
 41         n = len(data)
 42         mean = np.mean(data)
 43         sigma = np.cov(data)
 44         niu3_0 = data ** 3 / n
 45         return (niu3_0 - 3 * mean * sigma ** 2 - mean ** 3) / (sigma ** 3)
 46 
 47     def d_mea_abs_err(self, data):  # 平均绝对误差
 48         n = len(data)
 49         mean = np.mean(data)
 50         return sum(abs(data - mean)) / n
 51 
 52     def out_all(self, data):
 53         n = len(data)
 54         niu = sum(data) / n  # 均值
 55         niu2 = sum(data ** 2) / n
 56         niu3 = sum(data ** 3) / n  # 三阶原点矩
 57 
 58         sigma2 = niu2 - niu * niu  # 方差
 59         sigma = np.sqrt(sigma2)  # 标准差
 60         median = np.median(data)  # 中位数
 61 
 62         skewness = (niu3 - 3 * niu * sigma2 - niu ** 3) / (sigma ** 3)  # 偏度
 63         niu4_u = sum((data - niu) ** 4) / n  # 四阶中心矩
 64         kurtosis = niu4_u / (sigma ** 2) - 3  # 峰度
 65         mea_abs_err = sum(abs(data - niu)) / n  # 平均绝对误差
 66         return [niu, sigma, median, skewness, kurtosis, mea_abs_err]
 67 
 68 
 69 # 整合 5种数据生成、数据标签、数据保存
 70 class data_origin:
 71     def __init__(self, sampleNo):
 72         self.sampleNo = sampleNo  # 随机幅度样本个数
 73         # self.bins = bins  # 样本统计切片个数
 74         self.fun = {
 75             0: self.impulse,
 76             1: self.rayleigh,
 77             2: self.rice,
 78             3: self.lognormal,
 79             4: self.suzuki}
 80 
 81     def data_sum(self, num):
 82         d2_batch = []
 83         for i in range(num):
 84             select = np.random.randint(0, 5)
 85             fun_now = self.fun[select]
 86             data, d2 = fun_now()
 87             d1 = data_deal.out_all(self, data)
 88             d2_batch.append(d2)
 89             if i == 0:
 90                 d1_batch = d1
 91             else:
 92                 d1_batch = np.vstack((d1_batch, d1))
 93         return d1_batch, np.array(d2_batch)
 94 
 95     # 第一个 冲激分布  [1 0 0 0 0] 理论上完全正确
 96     def impulse(self):  # 测试正确
 97         mean = np.random.uniform(0.5, 2, 1)
 98 
 99         data = np.random.normal(mean, 0.001, self.sampleNo)
100         data = data / max(data)  # 数据归一化处理
101 
102         d2 = 0
103         return data, d2
104 
105     # 第二个 瑞利分布  [0 1 0 0 0]
106     def rayleigh(self):  # 使用理论生成数据(双高斯信号),测试正确
107         sigma = np.random.normal(2, 1, 1)[0]
108 
109         data0 = np.random.normal(loc=0.0, scale=abs(sigma), size=self.sampleNo)
110         data1 = np.random.normal(loc=0.0, scale=abs(sigma), size=self.sampleNo)
111         data = np.sqrt((data0 ** 2 + data1 ** 2))
112         data = data / max(data)  # 数据归一化处理
113 
114         d2 = 1
115         return data, d2
116 
117     # 第三个 莱斯分布  [0 0 1 0 0]
118     def rice(self):  # 测试正确
119         k = np.random.uniform(0, 15)
120         mean = np.sqrt(2 * k)
121 
122         data0 = np.random.normal(loc=0.0, scale=1, size=self.sampleNo)
123         data1 = np.random.normal(loc=0.0, scale=1, size=self.sampleNo)
124 
125         data = np.sqrt((data0 + mean) ** 2 + data1 ** 2)
126         data = data / max(data)  # 数据归一化处理
127 
128         d2 = 2
129         return data, d2
130 
131     # 第四个 对数正态分布  [0 0 0 1 0]
132     def lognormal(self):
133         u = 0  # 这里的u值可以通过归一化清除
134         delta = np.random.uniform(1 / 2, 1)  # delta的取值才是对数正态的核心
135 
136         data0 = np.random.normal(loc=0.0, scale=delta, size=self.sampleNo)
137         data = np.exp(u + delta * data0)
138         data = data / max(data)
139 
140         d2 = 3
141         return data, d2
142 
143     # 第五个 Suzuki分布  [0 0 0 0 1]
144     def suzuki(self):
145         m = np.random.normal(0, 1, 1)[0]  # 这里的sigma数值需要查数据,看看sigma的取值规律
146         s = np.random.uniform(0.3, 0.8)  # 这里的sigma数值需要查数据,看看sigma的取值规律
147 
148         data0 = np.random.normal(loc=0.0, scale=1, size=self.sampleNo)
149         data1 = np.random.normal(loc=0.0, scale=1, size=self.sampleNo)
150         data2 = np.random.normal(loc=0.0, scale=1, size=self.sampleNo)
151         u = np.sqrt(data0 ** 2 + data1 ** 2)
152         v = np.exp(m + s * data2)
153         data = u * v
154         data = data / max(data)
155 
156         d2 = 4
157         return data, d2
158 
159 
160 # 测试
161 # obj = data_origin(700, 1000)
162 # d1, d2 = obj.data_sum(20)
163 # d1, d2 = obj.impulse()
164 # print(d1)
165 # print(d1[19, 1])  # [batch_size,num]
166 # print(d2)
167 # show_ = show()
168 # print(d1)
169 # show_.broken_line(np.array(range(0, 1000)), d1)
170 # pass

 

附录代码:model.pyw

 1 # coding=utf-8
 2 
 3 
 4 # local1 全连接层 1     [6,128]
 5 # local2 全连接层 2     [128,512]
 6 # local3 全连接层 3     [512,128]
 7 # softmax 全连接层 4    [128,5]
 8 
 9 
10 import tensorflow as tf
11 
12 
13 def inference(images, batch_size, n_classes):
14     with tf.variable_scope('local1') as scope:
15         # reshape = tf.reshape(images, shape=[batch_size, -1])
16         # dim = reshape.get_shape()[1].value
17         # print(dim)
18         weights = tf.get_variable('weights',
19                                   shape=[6, 128],
20                                   dtype=tf.float32,
21                                   initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32))
22         biases = tf.get_variable('biases',
23                                  shape=[128],
24                                  dtype=tf.float32,
25                                  initializer=tf.constant_initializer(0.1))
26     local1 = tf.nn.relu(tf.matmul(images, weights) + biases, name=scope.name)
27 
28     # local2
29     with tf.variable_scope('local2') as scope:
30         weights = tf.get_variable('weights',
31                                   shape=[128, 512],
32                                   dtype=tf.float32,
33                                   initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32))
34         biases = tf.get_variable('biases',
35                                  shape=[512],
36                                  dtype=tf.float32,
37                                  initializer=tf.constant_initializer(0.1))
38         local2 = tf.nn.relu(tf.matmul(local1, weights) + biases, name='local4')
39 
40     # local3
41     with tf.variable_scope('local3') as scope:
42         weights = tf.get_variable('weights',
43                                   shape=[512, 128],
44                                   dtype=tf.float32,
45                                   initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32))
46         biases = tf.get_variable('biases',
47                                   shape=[128],
48                                   dtype=tf.float32,
49                                   initializer=tf.constant_initializer(0.1))
50         local3 = tf.nn.relu(tf.matmul(local2, weights) + biases, name='local4')
51 
52         # softmax
53     with tf.variable_scope('softmax_linear') as scope:
54         weights = tf.get_variable('softmax_linear',
55                                   shape=[128, n_classes],
56                                   dtype=tf.float32,
57                                   initializer=tf.truncated_normal_initializer(stddev=0.005, dtype=tf.float32))
58         biases = tf.get_variable('biases',
59                                  shape=[n_classes],
60                                  dtype=tf.float32,
61                                  initializer=tf.constant_initializer(0.1))
62         softmax_linear = tf.add(tf.matmul(local3, weights), biases, name='softmax_linear')
63 
64     return softmax_linear
65 
66 
67 def losses(logits, labels):
68     with tf.variable_scope('loss') as scope:
69         cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits \
70             (logits=logits, labels=labels, name='xentropy_per_example')
71         loss = tf.reduce_mean(cross_entropy, name='loss')
72         tf.summary.scalar(scope.name + '/loss', loss)
73     return loss
74 
75 
76 def trainning(loss, learning_rate, global_step):
77     # with tf.name_scope('optimizer'):
78     with tf.variable_scope('optimizer') as scope:
79         optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
80         # global_step = tf.Variable(0, name='global_step', trainable=False)
81         train_op = optimizer.minimize(loss, global_step=global_step)
82     return train_op
83 
84 
85 def evaluation(logits, labels):
86     with tf.variable_scope('accuracy') as scope:
87         correct = tf.nn.in_top_k(logits, labels, 1)
88         correct = tf.cast(correct, tf.float16)
89         accuracy = tf.reduce_mean(correct)
90         tf.summary.scalar(scope.name + '/accuracy', accuracy)
91     return accuracy

 

附录代码:train.pyw

 1 # coding=utf-8
 2 # 产生数据—训练-评估-结束标准
 3 # 这里使用的数据是随机生成的,理论上是穷举数据集,评估和训练本质上一致的
 4 '''
 5 改进:
 6 ① 将保存的训练参数使用相对路径
 7 
 8 '''
 9 
10 import input
11 import model
12 import numpy as np
13 import os
14 import tensorflow as tf
15 
16 bins = 6
17 sum_num = 1000
18 n_classes = 5
19 
20 BATCH_SIZE = 256
21 CAPACITY = 128
22 learn_rate = 0.0010485759
23 step_damp = 100
24 rate_damp = 0.9
25 MAX_STEP = 160000
26 
27 root_folder = os.path.dirname(os.path.realpath(__file__))
28 os.chdir(root_folder)  # 返回上一级文件夹
29 # print(root_folder)
30 # print(os.path.dirname(root_folder))
31 folder = "model2//"  # 使用相对路径
32 obj = input.data_origin(sum_num)
33 '''
34 DNN配置
35 '''
36 os.environ["CUDA_VISIBLE_DEVICES"] = '0'  # 指定第一块GPU可用
37 config = tf.ConfigProto(allow_soft_placement=True)
38 config.gpu_options.per_process_gpu_memory_fraction = 0.85  # 程序最多只能占用指定gpu 70%的显存
39 config.gpu_options.allow_growth = True  # 程序按需申请内存
40 with tf.Session(config=config) as sess:
41     global_step = tf.Variable(0, name='global_step', trainable=False)  # 有变更,需要注意
42     learning_rate = tf.train.exponential_decay(learn_rate, global_step, step_damp, rate_damp, staircase=False)
43 
44     data_batch = tf.placeholder(dtype=tf.float32, shape=[BATCH_SIZE, bins], name='data')
45     label_batch = tf.placeholder(dtype=tf.int32, shape=[BATCH_SIZE], name='label')
46 
47     train_logits = model.inference(data_batch, BATCH_SIZE, n_classes)
48     train_loss = model.losses(train_logits, label_batch)
49     train_op = model.trainning(train_loss, learning_rate, global_step)
50     train__acc = model.evaluation(train_logits, label_batch)
51 
52     summary_op = tf.summary.merge_all()
53     train_writer = tf.summary.FileWriter(folder, sess.graph)
54     saver = tf.train.Saver()
55 
56     sess.run(tf.global_variables_initializer())
57     for step in np.arange(MAX_STEP):
58         data, label = obj.data_sum(BATCH_SIZE)
59         _ = sess.run(train_op, {data_batch: data, label_batch: label})
60         if step % step_damp == 0:
61             step_now, tra_loss, learn_rate, accuracy_now = sess.run(
62                 [global_step, train_loss, learning_rate, train__acc], {data_batch: data, label_batch: label})
63 
64             print('Step %d, train_loss = %f ,accuracy = %f ,learn_rate = %.10f ' % (
65             step_now, tra_loss, accuracy_now, learn_rate))
66         if (step % 10000 == 0) or ((step + 1) == MAX_STEP):
67             checkpoint_path = os.path.join(folder, 'model.ckpt')
68             saver.save(sess, checkpoint_path, global_step=step)

 

附录代码:evaluate.pyw

 1 # coding=utf-8
 2 # 产生数据—训练-评估-结束标准
 3 # 这里使用的数据是随机生成的,理论上是穷举数据集,评估和训练本质上一致的
 4 """
 5 改进:
 6 ① 将保存的训练参数使用相对路径
 7 
 8 """
 9 
10 import input
11 import model
12 import numpy as np
13 import os
14 import tensorflow as tf
15 
16 bins = 6
17 sum_num = 1000
18 n_classes = 5
19 
20 BATCH_SIZE = 2048
21 CAPACITY = 128
22 step = 10
23 
24 root_folder = os.path.dirname(os.path.realpath(__file__))
25 os.chdir(root_folder)  # 返回上一级文件夹
26 
27 logs_train_dir = "model2"  # 使用相对路径
28 obj = input.data_origin(sum_num)
29 
30 
31 def evaluate(logs_train_dir, BATCH_SIZE):
32     # GPU计算资源参数
33     os.environ["CUDA_VISIBLE_DEVICES"] = '0'  # 指定第一块GPU可用
34     config = tf.ConfigProto(allow_soft_placement=True)
35     config.gpu_options.per_process_gpu_memory_fraction = 0.85  # 程序最多只能占用指定gpu 70%的显存
36     config.gpu_options.allow_growth = True  # 程序按需申请内存
37     with tf.Session(config=config) as sess:
38 
39         data_batch = tf.placeholder(dtype=tf.float32, shape=[BATCH_SIZE, bins], name='data')
40         label_batch = tf.placeholder(dtype=tf.int32, shape=[BATCH_SIZE], name='label')
41 
42         train_logits = model.inference(data_batch, BATCH_SIZE, n_classes)
43         # evaluate_logits = tf.nn.softmax(train_logits)
44         evaluate_logits = tf.argmax(train_logits, 1)
45         train__acc = model.evaluation(train_logits, label_batch)
46 
47         # 计算图保存参数
48         # summary_op = tf.summary.merge_all()
49         # train_writer = tf.summary.FileWriter(logs_train_dir, sess.graph)
50         saver = tf.train.Saver()
51 
52         sess.run(tf.global_variables_initializer())
53         # coord = tf.train.Coordinator()
54         # threads = tf.train.start_queue_runners(sess=sess, coord=coord)
55 
56         # 加载训练后的参数
57         ckpt = tf.train.get_checkpoint_state(logs_train_dir)
58         if ckpt and ckpt.model_checkpoint_path:
59             global_step = ckpt.model_checkpoint_path.split('/')[-1].split('-')[-1]
60             saver.restore(sess, ckpt.model_checkpoint_path)
61             print('模型加载成功, 训练的步数为 %s' % global_step)
62         else:
63             print('模型加载失败,,,文件没有找到')
64 
65         # 写入预测数据前期设置
66         try:
67             for i in np.arange(step):
68                 data, label = obj.data_sum(BATCH_SIZE)
69                 # if coord.should_stop():
70                 #     break
71                 # accuracy_now, prediction = sess.run([train__acc, evaluate_logits],
72                 #                                     {data_batch: data, label_batch: label})
73                 # print('accuracy = %f' % (accuracy_now), 'label is ', label, 'prediction is ', prediction)
74 
75                 accuracy_now = sess.run(train__acc,{data_batch: data, label_batch: label})
76                 print('accuracy = %f' % accuracy_now)
77 
78         except tf.errors.OutOfRangeError:
79             print('Done training -- epoch limit reached')
80         # finally:
81         #     coord.request_stop()
82         # coord.join(threads)
83         # print("正常预测第", circle, "个数据", label[circle])
84     sess.close()
85 
86 
87 evaluate(logs_train_dir, BATCH_SIZE)

 

posted on 2018-12-17 14:51  周健康  阅读(1221)  评论(0编辑  收藏  举报

导航