Python-多维矩阵添加高斯噪声

Python-多维矩阵添加高斯噪声

文章目录

  • Python-多维矩阵添加高斯噪声
    • 步骤一:创建多维矩阵
        • 涉及知识点
          • 1. 利用numpy创建多维随机矩阵
          • 2. 查看变量的数据类型
          • 3. 将变量的数据类型由float64转换为float32
    • 步骤二:定义添加高斯噪声的函数
      • 方法一:向多维矩阵中的元素逐个添加高斯噪声
        • 涉及知识点
          • 1. 获取变量的大小
          • 2. 生成具有高斯分布的随机浮点数
      • 方法二:定义一个与多维矩阵等大的高斯噪声矩阵,直接与多维矩阵相加即可添加高斯噪声
        • 涉及知识点
          • 1. 生成具有高斯分布特征的随机矩阵
    • 整体代码

内容简介

总共有两个步骤:①创建多维矩阵,作为添加高斯噪声的对象;②定义高斯噪声添加的函数,在其中创建噪声并添加到原噪声中。

步骤一:创建多维矩阵

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)

涉及知识点

1. 利用numpy创建多维随机矩阵

使用函数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()生成的矩阵。

2. 查看变量的数据类型

使用type()函数,可以查看变量的数据类型。如:

matrix = np.random.random(size=[4, 20, 15])
print(type(matrix)) # 输出结果为:,表示matrix这个变量是使用numpy生成的一个array
print(type(matrix[0][0][0])) # 输出结果为:,表示matrix这个数组中的元素的数据类型是float64
3. 将变量的数据类型由float64转换为float32

使用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π σ1e2σ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的第一行元素

涉及知识点

1. 获取变量的大小

使用len()函数。如:

channel_size = len(matrix)
# 输出结果为4,表示matrix矩阵第一维大小为4
2. 生成具有高斯分布的随机浮点数

使用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的第一行元素

涉及知识点

1. 生成具有高斯分布特征的随机矩阵

使用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)

你可能感兴趣的:(python)