噪声
高斯噪声
高斯噪声是指它的概率密度函数服从高斯分布(即正态分布)的一类噪声。常见的高斯噪声包括起伏噪声、宇宙噪声、热噪声和散粒噪声等等。除常用抑制噪声的方法外,对高斯噪声的抑制方法常常采用数理统计方法。
所谓高斯噪声是指它的概率密度函数服从高斯分布(即正态分布)的一类噪声。如果一个噪声,它的幅度分布服从高斯分布,而它的功率谱密度又是均匀分布的,则称它为高斯白噪声。高斯白噪声的二阶矩不相关,一阶矩为常数,是指先后信号在时间上的相关性。高斯白噪声包括热噪声和散粒噪声。在通信信道测试和建模中,高斯噪声被用作加性白噪声以产生加性白高斯噪声。
添加高斯噪声
来源:
https://blog.csdn.net/mikumiku339/article/details/109534376?ops_request_misc=&request_id=&biz_id=102&utm_term=%E9%AB%98%E6%96%AF%E5%99%AA%E5%A3%B0python&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0-109534376.nonecase&spm=1018.2226.3001.4187
先将原图片的像素值除以255,即将像素值区间[0,255]投射到[0,1],再添加服从高斯分布的噪声,最后将处理后的像素矩阵乘255恢复。
代码:
import cv2
import numpy as np
def Gaussnoise_func(image, mean=0, var=0.005):
'''
添加高斯噪声
mean : 均值
var : 方差
'''
image = np.array(image/255, dtype=float) #将像素值归一
noise = np.random.normal(mean, var ** 0.5, image.shape) #产生高斯噪声
out = image + noise #直接将归一化的图片与噪声相加
'''
将值限制在(-1/0,1)间,然后乘255恢复
'''
if out.min() < 0:
low_clip = -1.
else:
low_clip = 0.
out = np.clip(out, low_clip, 1.0)
out = np.uint8(out*255)
return out
def nothing(pp):
pass
if __name__ == '__main__':
img = cv2.imread("apple.png")
#创建预览界面
cv2.namedWindow("Preview")
cv2.createTrackbar("mean","Preview",0,5,nothing)
cv2.createTrackbar("var","Preview",0,5,nothing)
while(1):
mean = cv2.getTrackbarPos("mean","Preview")
var = cv2.getTrackbarPos("var","Preview")
img_r = Gaussnoise_func(img,mean/10,var/100)
cv2.imshow("Result",img_r)
k = cv2.waitKey(1) & 0xff
if k == 27:
break
cv2.destroyAllWindows()
高斯噪声,顾名思义是指服从高斯分布(正态分布)的一类噪声。有的时候我们需要向标准数据中加入合适的高斯噪声让数据更加符合实际。
python中的random库中集成了高斯正态分布,可以直接使用。
我们可以通过调整高斯噪声均值和方差,获取不同效果的处理数据。
import random
import numpy as np
from matplotlib import pyplot as plt
def gauss_noisy(x, y):
"""
对输入数据加入高斯噪声
:param x: x轴数据
:param y: y轴数据
:return:
"""
mu = 0
sigma = 0.05
for i in range(len(x)):
x[i] += random.gauss(mu, sigma)
y[i] += random.gauss(mu, sigma)
if __name__ == '__main__':
# 在0-5的区间上生成50个点作为测试数据
xl = np.linspace(0, 5, 50, endpoint=True)
yl = np.sin(xl)
# 加入高斯噪声
gauss_noisy(xl, yl)
# 画出这些点
plt.plot(xl, yl, linestyle='', marker='.')
plt.show()
椒盐噪声
椒盐噪声(salt-and-pepper noise)是指两种噪声,一种是盐噪声(salt noise),另一种是胡椒噪声(pepper noise)。盐=白色(0),椒=黑色(255)。前者是高灰度噪声,后者属于低灰度噪声。一般两种噪声同时出现,呈现在图像上就是黑白杂点。
添加噪声
安装skimage库
// python-numpy
// python-scipy
// python-matplotlib
$ sudo apt-get install python-numpy
$ sudo apt-get install python-scipy
$ sudo apt-get install python-matplotlib
安装python-scikit-image
$ sudo apt-get install python-skimage
实战
σ
\sigma
σ=0.01
高斯噪声分别给数据集和测试集加上高斯噪声:
以下四张图分别为:
数据集——测试集
原——原
高斯——原
原——高斯
高斯——高斯
卷积神经网络
二维卷积层
卷积神经网络是含有卷积层的神经网络。
在二维卷积层中,一个二维输入数组和一个二维核数组通过互相关运算输出一个二维数组。
如图,输入的是一个高和宽均为3的二维数组。
将该数组的形状记为3x3或(3,3)
核数组的高和宽分别为2.
该数组在卷积运算中又称卷积核或过滤器。
卷积核窗口(又称卷积窗口)的形状取决于卷积核的高和宽,即2x2
在二维互相关运算中,卷积窗口从输入张量的左上角开始,从左到右、从上到下滑动。
当卷积窗口滑动到新一个位置时,包含在该窗口中的部分张量与卷积核张量进行按元素相乘,得到的张量再求和得到一个单一的标量值,由此我们得出了这一位置的输出张量值。
import torch
from torch import nn
from d2l import torch as d2l
def corr2d(X, K): #@save
"""计算二维互相关运算"""
h, w = K.shape
Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):
Y[i, j] = (X[i:i + h, j:j + w] * K).sum()
return Y
图像中物体边缘检测
如下是卷积层的一个简单应用:通过找到像素变化的位置,来检测图像中不同颜色的边缘。 首先,我们构造一个像素的黑白图像。中间四列为黑色(0),其余像素为白色(1)。
X = torch.ones((6, 8))
X[:, 2:6] = 0
print(X)
输出
tensor([[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.],
[1., 1., 0., 0., 0., 0., 1., 1.]])
接下来,我们构造一个高度为1、宽度为2的卷积核K。
当进行互相关运算时,如果水平相邻的两元素相同,则输出为0,否则输出为非0。
K = torch.tensor([[1.0, -1.0]])
现在,我们对参数X(输入)和K(卷积核)执行互相关运算。 如下所示,输出Y中的1代表从白色到黑色的边缘,-1代表从黑色到白色的边缘,其他情况的输出为0。
Y = corr2d(X, K)
print(Y)
tensor([[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.],
[ 0., 1., 0., 0., 0., -1., 0.]])
LeNet
总体来看,LeNet(LeNet-5)由两个部分组成:
- 卷积编码器(卷积层块):由两个卷积层组成
- 全连接层密集块:由三个全连接层组成。
卷积层快里的基本单位是卷积层后接最大池化层:卷积层用来识别图像里的空间模式,如线条和物体局部,之后的最大池化层则用来降低卷积层对位置的敏感性。
卷积层快由两个这样的基本单位堆叠而成。
卷积层快的输出形状为(批量大小,通道,高,宽),当卷积层快的输出传入全连接层快时,全连接层快会将小批量中每个样本变平。
也就是说,全连接层的输入形状将变成二维,其中第一维是小批量中的样本,第二维是每个样本变平后的向量表示,且向量长度为通道、高和宽的乘积。
import torch
from torch import nn
from d2l import torch as d2l
net = nn.Sequential(
nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),
nn.AvgPool2d(kernel_size=2, stride=2),
nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),
nn.AvgPool2d(kernel_size=2, stride=2),
nn.Flatten(),
nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
nn.Linear(120, 84), nn.Sigmoid(),
nn.Linear(84, 10))
X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:
X = layer(X)
print(layer.__class__.__name__,'output shape: \t',X.shape)
`
> Conv2d output shape: torch.Size([1, 6, 28, 28])
Sigmoid output shape: torch.Size([1, 6, 28, 28])
AvgPool2d output shape: torch.Size([1, 6, 14, 14])
Conv2d output shape: torch.Size([1, 16, 10, 10])
Sigmoid output shape: torch.Size([1, 16, 10, 10])
AvgPool2d output shape: torch.Size([1, 16, 5, 5])
Flatten output shape: torch.Size([1, 400])
Linear output shape: torch.Size([1, 120])
Sigmoid output shape: torch.Size([1, 120])
Linear output shape: torch.Size([1, 84])
Sigmoid output shape: torch.Size([1, 84])
长短期记忆网络(LSTM)
部分代码来源:
https://github.com/d2l-ai/d2l-zh
长短期记忆
长短期记忆中输入门、遗忘门和输出门的计算
长短期记忆中候选记忆细胞的计算
长短期记忆中记忆细胞的计算
长短期记忆中隐藏状态的计算
代码实现
加载数据集
import torch
from torch import nn
from d2l import torch as d2l
batch_size, num_steps = 32, 35
train_iter, vocab = d2l.load_data_time_machine(batch_size, num_steps)
初始化模型参数
def get_lstm_params(vocab_size, num_hiddens, device):
num_inputs = num_outputs = vocab_size
def normal(shape):
return torch.randn(size=shape, device=device)*0.01
def three():
return (normal((num_inputs, num_hiddens)),
normal((num_hiddens, num_hiddens)),
torch.zeros(num_hiddens, device=device))
W_xi, W_hi, b_i = three() # 输入门参数
W_xf, W_hf, b_f = three() # 遗忘门参数
W_xo, W_ho, b_o = three() # 输出门参数
W_xc, W_hc, b_c = three() # 候选记忆元参数
# 输出层参数
W_hq = normal((num_hiddens, num_outputs))
b_q = torch.zeros(num_outputs, device=device)
# 附加梯度
params = [W_xi, W_hi, b_i, W_xf, W_hf, b_f, W_xo, W_ho, b_o, W_xc, W_hc,
b_c, W_hq, b_q]
for param in params:
param.requires_grad_(True)
return params
定义模型
def init_lstm_state(batch_size, num_hiddens, device):
return (torch.zeros((batch_size, num_hiddens), device=device),
torch.zeros((batch_size, num_hiddens), device=device))
def lstm(inputs, state, params):
[W_xi, W_hi, b_i, W_xf, W_hf, b_f, W_xo, W_ho, b_o, W_xc, W_hc, b_c,
W_hq, b_q] = params
(H, C) = state
outputs = []
for X in inputs:
I = torch.sigmoid((X @ W_xi) + (H @ W_hi) + b_i)
F = torch.sigmoid((X @ W_xf) + (H @ W_hf) + b_f)
O = torch.sigmoid((X @ W_xo) + (H @ W_ho) + b_o)
C_tilda = torch.tanh((X @ W_xc) + (H @ W_hc) + b_c)
C = F * C + I * C_tilda
H = O * torch.tanh(C)
Y = (H @ W_hq) + b_q
outputs.append(Y)
return torch.cat(outputs, dim=0), (H, C)
训练模型
vocab_size, num_hiddens, device = len(vocab), 256, d2l.try_gpu()
num_epochs, lr = 500, 1
model = d2l.RNNModelScratch(len(vocab), num_hiddens, device, get_lstm_params,
init_lstm_state, lstm)
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)
简洁实现
num_inputs = vocab_size
lstm_layer = nn.LSTM(num_inputs, num_hiddens)
model = d2l.RNNModel(lstm_layer, len(vocab))
model = model.to(device)
d2l.train_ch8(model, train_iter, vocab, lr, num_epochs, device)