总共有两个步骤:①创建多维矩阵,作为添加高斯噪声的对象;②定义高斯噪声添加的函数,在其中创建噪声并添加到原噪声中。
if __name__ == '__main__':
# 生成一个三维的小数矩阵,模拟4张特征图,每一张特征图有20行,15列
matrix = np.random.random(size=[4, 20, 15])
# print(type(matrix)) # numpy.ndarray
# print(type(matrix[0][0][0])) # numpy.float64
# 转换成numpy.float32
matrix_new = matrix.astype(np.float32)
# print(type(matrix_new[0][0][0])) # numpy.float32
print(">>>>>>>>>before adding gaussain noise")
print(matrix_new[0][0])
# 加入高斯噪声(方法一)
gauss_noise(matrix_new, 0.2)
# 加入高斯噪声(方法二)
gauss_noise_matrix(matrix_new, 0.2)
使用函数np.random.random(),生成的矩阵中的元素为float型,大小范围为 [ 0.0 , 1.0 ) [0.0, 1.0) [0.0,1.0)。使用方法详见:numpy.random.random
也可使用函数np.random.randint(),生成的矩阵中的元素为int型,大小范围可自定义。使用方法详见:numpy.random.randint
创建小数矩阵还是整数矩阵?
如果要添加高斯噪声,因为高斯噪声本身遵循高斯分布,而高斯分布的曲线能够达到的最大值为 1 2 π σ \frac{1}{\sqrt{2\pi} \sigma} 2πσ1,当 σ = 1 \sigma = 1 σ=1时,高斯分布曲线最大值约为0.3989;当 σ = 0.2 \sigma = 0.2 σ=0.2时,最大值约为1.9947。只有在 σ \sigma σ的值非常小的情况下曲线最大值才会比较大(至少大于2)。
但是一般使用的 σ \sigma σ值比较小(不大于1),则曲线最大值不会大于1,那么使用函数np.random.random()生成的矩阵可以对施加的高斯噪声更敏感,也就是添加的噪声对原矩阵的干扰更大,所以在后面的案例中,我们使用函数np.random.random()生成的矩阵。
使用type()函数,可以查看变量的数据类型。如:
matrix = np.random.random(size=[4, 20, 15])
print(type(matrix)) # 输出结果为:,表示matrix这个变量是使用numpy生成的一个array
print(type(matrix[0][0][0])) # 输出结果为:,表示matrix这个数组中的元素的数据类型是float64
使用astype()函数,可以将变量的数据类型进行转换。如:
matrix = np.random.random(size=[4, 20, 15])
matrix_new = matrix.astype(np.float32) # 将matrix中元素的数据类型由float64转换为float32
# 注意:①参数要带上np,而不是'float32'或者直接写float32,那样会转换失败;②要使用一个新的变量来承接转换结果
为什么要将元素的数据类型由float64转换为float32?
内存空间占用上,float32占用空间更小:float64在内存中占用64bits,即8bytes的空间大小;float32在内存中占用32bits,即4bytes的空间大小。当数据量大的时候,float32占用的空间比用float64小得多。在对数据精度没有很高要求的情况下,进行网络训练时,使用float32可以提高运算效率。
float64和float32的区别参考:float32和float64的本质区别(类型对深度学习影响以及python的使用)
根据高斯分布公式 f ( x ) = 1 2 π σ e − ( x − μ ) 2 2 σ 2 f(x) = \frac{1}{\sqrt{2\pi} \sigma} e ^ {- \frac{(x - \mu) ^ 2}{2 \sigma ^ 2}} f(x)=2πσ1e−2σ2(x−μ)2,高斯噪声由两个变量控制: μ \mu μ和 σ \sigma σ,因此要提供这两个参数。
def gauss_noise(matrix, sigma):
mu = 0 # 高斯噪声的第一个参数mu
# 高斯噪声的第二个参数sigma在这里写成了由调用此函数的函数输入
# 1. 因为是向多维矩阵中的元素逐个添加高斯噪声,所以要先获取矩阵的大小。这里我因为事先知道输入的矩阵大小,所以没有做特殊情况的判断,直接获取channel大小、矩阵行数height和矩阵列数width。
channel_size = len(matrix)
height = len(matrix[0])
width = len(matrix[0][0])
# print("matrix_shape: channel_size: {}, height: {}, width: {}".format(channel_size, height, width))
# 2. 遍历多维矩阵中的元素,逐个添加高斯噪声
for channel in range(0, channel_size):
for i in range(0, height):
for j in range(0, width):
matrix[channel][i][j] += random.gauss(mu, sigma)
# 3. 输出添加噪声后的矩阵
print(">>>>>>>>>added gaussain noise with method 1")
print(matrix[0][0]) # 这里为了方便观察,只输出了第一个channel的第一行元素
使用len()函数。如:
channel_size = len(matrix)
# 输出结果为4,表示matrix矩阵第一维大小为4
使用random.gauss()函数,返回具有高斯分布的随机浮点数。使用方法详见:random.gauss() function in Python
示例:
add_gauss = random.gauss(mu, sigma)
# print("add_gauss: {}, type: {}".format(add_gauss, type(add_gauss))) # type: 'float'
def gauss_noise_matrix(matrix, sigma):
# 1. 定义一个与多维矩阵等大的高斯噪声矩阵
mu = 0
channel_size = len(matrix)
height = len(matrix[0])
width = len(matrix[0][0])
noise_matrix = np.random.normal(mu, sigma, size=[channel_size, height, width]).astype(np.float32) # 这里在生成噪声矩阵的同时将其元素数据类型转换为float32
# print("noise_matrix_element_type: {}".format(type(noise_matrix[0][0][0]))) # numpy.float32
print(noise_matrix[0][0]) # 这里为了方便观察,只输出了第一个channel的第一行元素
# 2. 与原来的多维矩阵相加,即可达到添加高斯噪声的效果
matrix += noise_matrix
# 3. 输出添加噪声后的矩阵
print(">>>>>>>>>added gaussain noise with method 2")
print(matrix[0][0]) # 这里为了方便观察,只输出了第一个channel的第一行元素
使用random.normal()函数,返回具有高斯分布特征的矩阵。使用方法详见:numpy.random.normal
import numpy as np
import random
# 方法一:逐个元素添加噪声
def gauss_noise(matrix, sigma):
mu = 0
channel_size = len(matrix)
height = len(matrix[0])
width = len(matrix[0][0])
# print("matrix_shape: channel_size: {}, height: {}, width: {}".format(channel_size, height, width))
for channel in range(0, channel_size):
for i in range(0, height):
for j in range(0, width):
matrix[channel][i][j] += random.gauss(mu, sigma)
print(">>>>>>>>>added gaussain noise with method 1")
print(matrix[0][0])
# print(type(matrix[0][0][0])) # numpy.float32
# 方法二:等大噪声矩阵添加噪声
def gauss_noise_matrix(matrix, sigma):
mu = 0
channel_size = len(matrix)
height = len(matrix[0])
width = len(matrix[0][0])
noise_matrix = np.random.normal(mu, sigma, size=[channel_size, height, width]).astype(np.float32)
# print("noise_matrix_element_type: {}".format(type(noise_matrix[0][0][0]))) # numpy.float32
print(noise_matrix[0][0])
matrix += noise_matrix
print(">>>>>>>>>added gaussain noise with method 2")
print(matrix[0][0])
if __name__ == '__main__':
# 生成一个四维小数矩阵,21行,25列
matrix = np.random.random(size=[4, 21, 25])
# print(type(matrix)) # numpy.ndarray
# print(type(matrix[0][0][0])) # numpy.float64
# 转换成numpy.float32
matrix_new = matrix.astype(np.float32)
# print(type(matrix_new[0][0][0])) # numpy.float32
print(">>>>>>>>>before adding gaussain noise")
print(matrix)
# print(matrix_new[0][0])
# 加入高斯噪声(方法一)
gauss_noise(matrix_new, 0.2)
# 加入高斯噪声(方法二)
gauss_noise_matrix(matrix_new, 0.2)