图片缩放(最近邻插值(Nearest Neighbor interpolation))

Credits: https://blog.csdn.net/haluoluo211/article/details/80918147

基本原理

最简单的图像缩放算法就是最近邻插值。顾名思义,就是将目标图像各点的像素值设为源图像中与其最近的点。算法优点在与简单、速度快。

如下图所示,一个4*4的图片缩放为8*8的图片。步骤:

  1. 生成一张空白的8*8的图片,然后在缩放位置填充原始图片值(可以这么理解)
  2. 在图片的未填充区域(黑色部分),填充为原有图片最近的位置的像素值。

这里写图片描述


实现代码如下:

def nearest_neighbor_resize(img, new_w, new_h):
    # height and width of the input img
    h, w = img.shape[0], img.shape[1]
    # new image with rgb channel
    ret_img = np.zeros(shape=(new_h, new_w, 3), dtype='uint8')
    # scale factor
    s_h, s_c = (h * 1.0) / new_h, (w * 1.0) / new_w

    # insert pixel to the new img
    for i in xrange(new_h):
        for j in xrange(new_w):
            p_x = int(j * s_c)
            p_y = int(i * s_h)

            ret_img[i, j] = img[p_y, p_x]

    return ret_img

 

测试代码如下:

def test():
    img_path = 'F:/nearest_neighbor.jpg'
    img = cv2.imread(img_path)

    ret_img = nearest_neighbor_resize(img, 222, 220)

    cv2.imshow("source image", img)
    cv2.imshow("after bilinear image", ret_img)
    cv2.waitKey()
    cv2.destroyAllWindows()

运行结果如下:

这里写图片描述

主要参考:

http://tech-algorithm.com/articles/nearest-neighbor-image-scaling/


Credits: https://blog.csdn.net/haluoluo211/article/details/80918147

Advertisements

(转)TensorFlow strides 参数讨论

转自:https://blog.csdn.net/lanchunhui/article/details/61615714

卷积神经网络(CNN)在 TensorFlow 实现时涉及的 tf.nn.con2d(二维卷积)、tf.nn.max_pool(最大池化)、tf.nn.avg_pool(平均池化)等操作都有关于 strides(步长)的指定,因为无论是卷积操作还是各种类型的池化操作,都是某种形式的滑动窗口(sliding window)处理,这就要求指定从当前窗口移动下一个窗口位置的移动步长。

TensorFlow 文档关于 strides的说明如下:

strides: A list of ints that has length >= 4. The stride of the sliding window for each dimension of the input tensor.
首先要求 strides 为长度不小于 4 的整数构成的 list,strides参数表示的是滑窗在输入张量各个维度上的移动步长。

而且一般要求 strides的参数,strides[0] = strides[3] = 1

具体什么含义呢?

一般而言,对于输入张量(input tensor)有四维信息:[batch, height, width, channels](分别表示 batch_size, 也即样本的数目,单个样本的行数和列数,样本的频道数,rgb图像就是三维的,灰度图像则是一维),对于一个二维卷积操作而言,其主要作用在 height, width上。

strides参数确定了滑动窗口在各个维度上移动的步数。一种常用的经典设置就是要求,strides[0]=strides[3]=1

  • strides[0] = 1,也即在 batch 维度上的移动为 1,也就是不跳过任何一个样本,否则当初也不该把它们作为输入(input)
  • strides[3] = 1,也即在 channels 维度上的移动为 1,也就是不跳过任何一个颜色通道;

 


转自:https://blog.csdn.net/lanchunhui/article/details/61615714

(转)Numpy学习——数组填充np.pad()函数的应用

转自:https://blog.csdn.net/zenghaitao0128/article/details/78713663

 

在卷积神经网络中,为了避免因为卷积运算导致输出图像缩小和图像边缘信息丢失,常常采用图像边缘填充技术,即在图像四周边缘填充0,使得卷积运算后图像大小不会缩小,同时也不会丢失边缘和角落的信息。在Python的numpy库中,常常采用numpy.pad()进行填充操作,具体分析如下:

1. np.pad()函数

1)语法结构

pad(array, pad_width, mode, **kwargs)

返回值:数组

2)参数解释

array——表示需要填充的数组;

pad_width——表示每个轴(axis)边缘需要填充的数值数目。
参数输入方式为:((before_1, after_1), … (before_N, after_N)),其中(before_1, after_1)表示第1轴两边缘分别填充before_1个和after_1个数值。取值为:{sequence, array_like, int}

mode——表示填充的方式(取值:str字符串或用户提供的函数),总共有11种填充模式;

3) 填充方式

‘constant’——表示连续填充相同的值,每个轴可以分别指定填充值,constant_values=(x, y)时前面用x填充,后面用y填充,缺省值填充0

‘edge’——表示用边缘值填充

‘linear_ramp’——表示用边缘递减的方式填充

‘maximum’——表示最大值填充

‘mean’——表示均值填充

‘median’——表示中位数填充

‘minimum’——表示最小值填充

‘reflect’——表示对称填充

‘symmetric’——表示对称填充

‘wrap’——表示用原数组后面的值填充前面,前面的值填充后面

import numpy as np
  • 1

1.1 常数填充模式——’constant’

在卷积神经网络中,通常采用constant填充方式!!

A = np.arange(95,99).reshape(2,2)    #原始输入数组
A
  • 1
  • 2
array([[95, 96],
       [97, 98]])
  • 1
  • 2
  • 3

1.1.1 用例1

#在数组A的边缘填充constant_values指定的数值
#(3,2)表示在A的第[0]轴填充(二维数组中,0轴表示行),即在0轴前面填充3个宽度的0,比如数组A中的95,96两个元素前面各填充了3个0;在后面填充2个0,比如数组A中的97,98两个元素后面各填充了2个0
#(2,3)表示在A的第[1]轴填充(二维数组中,1轴表示列),即在1轴前面填充2个宽度的0,后面填充3个宽度的0
np.pad(A,((3,2),(2,3)),'constant',constant_values = (0,0))  #constant_values表示填充值,且(before,after)的填充值等于(0,0)
  • 1
  • 2
  • 3
  • 4
array([[ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0, 95, 96,  0,  0,  0],
       [ 0,  0, 97, 98,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
#填充时,从前面轴,往后面轴依次填充
np.pad(A,((3,2),(2,3)),'constant',constant_values = (-2,2))   #填充值,前面填充改为-2,后面填充改为2
  • 1
  • 2
array([[-2, -2, -2, -2,  2,  2,  2],
       [-2, -2, -2, -2,  2,  2,  2],
       [-2, -2, -2, -2,  2,  2,  2],
       [-2, -2, 95, 96,  2,  2,  2],
       [-2, -2, 97, 98,  2,  2,  2],
       [-2, -2,  2,  2,  2,  2,  2],
       [-2, -2,  2,  2,  2,  2,  2]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
np.pad(A,((3,2),(2,3)),'constant',constant_values = ((0,0),(1,2)))    #0轴和1轴分别填充不同的值,先填充0轴,后填充1轴,存在1轴填充覆盖0轴填充的情形
  • 1
array([[ 1,  1,  0,  0,  2,  2,  2],
       [ 1,  1,  0,  0,  2,  2,  2],
       [ 1,  1,  0,  0,  2,  2,  2],
       [ 1,  1, 95, 96,  2,  2,  2],
       [ 1,  1, 97, 98,  2,  2,  2],
       [ 1,  1,  0,  0,  2,  2,  2],
       [ 1,  1,  0,  0,  2,  2,  2]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
np.pad(A,((3,2),(2,3)),'constant')     #,constant_values 缺省,则默认填充均为0
  • 1
array([[ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0, 95, 96,  0,  0,  0],
       [ 0,  0, 97, 98,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

1.2 边缘值填充模式——’edge’

B = np.arange(1,5).reshape(2,2)  #原始输入数组
B
  • 1
  • 2
array([[1, 2],
       [3, 4]])
  • 1
  • 2
  • 3
np.pad(B,((1,2),(2,1)),'edge')   #注意先填充0轴,后面填充1轴,依次填充
  • 1
array([[1, 1, 1, 2, 2],
       [1, 1, 1, 2, 2],
       [3, 3, 3, 4, 4],
       [3, 3, 3, 4, 4],
       [3, 3, 3, 4, 4]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

1.3 边缘最大值填充模式——’maximum’

B = np.arange(1,5).reshape(2,2)  #原始输入数组
B
  • 1
  • 2
array([[1, 2],
       [3, 4]])
  • 1
  • 2
  • 3
np.pad(B,((1,2),(2,1)),'maximum')    #maximum填充模式还有其他控制参数,比如stat_length,详细见numpy库
  • 1
array([[4, 4, 3, 4, 4],
       [2, 2, 1, 2, 2],
       [4, 4, 3, 4, 4],
       [4, 4, 3, 4, 4],
       [4, 4, 3, 4, 4]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
C = np.arange(0,9).reshape(3,3)  #原始输入数组
C
  • 1
  • 2
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
  • 1
  • 2
  • 3
  • 4
np.pad(C,((3,2),(2,1)),'maximum')  
  • 1
array([[8, 8, 6, 7, 8, 8],
       [8, 8, 6, 7, 8, 8],
       [8, 8, 6, 7, 8, 8],
       [2, 2, 0, 1, 2, 2],
       [5, 5, 3, 4, 5, 5],
       [8, 8, 6, 7, 8, 8],
       [8, 8, 6, 7, 8, 8],
       [8, 8, 6, 7, 8, 8]])

 


转自:https://blog.csdn.net/zenghaitao0128/article/details/78713663

(转)numpy基本用法多维数组

 

转自:https://blog.csdn.net/jacke121/article/details/76146884


对于Python中的numpy模块,一般用其提供的ndarray对象。

创建一个ndarray对象很简单,只要将一个list作为参数即可。
例如

 

使用array函数创建时,参数必须是由方括号括起来的列表,而不能使用多个数值作为参数调用array

  1. >>> a = array(1,2,3,4)    # 错误
  2. >>> a = array([1,2,3,4])  # 正确

可使用双重序列来表示二维的数组,三重序列表示三维数组,以此类推。

  1. >>> b = array( [ (1.5,2,3), (4,5,6) ] )
  2. >>> b
  3.     array([[ 1.5,  2. ,  3. ],
  4.         [ 4. ,  5. ,  6. ]])
import numpy as np #引入numpy库

#创建一维的narray对象
a = np.array([1,2,3,4,5])

#创建二维的narray对象
a2 = np.array([[1,2,3,4,5],[6,7,8,9,10]])

#创建多维对象以其类推
复制代码

 


  获取矩阵行数列数(二维情况)

习惯了采用matlab进行数模的编程,要对矩阵进行遍历时,一般先获取矩阵的行数和列数。要获取narray对象的各维的长度,可以通过narray对象的shape属性

import numpy as np
a = np.array([[1,2,3,4,5],[6,7,8,9,10]])

print(a.shape) #结果返回一个tuple元组 (2L, 5L)
print(a.shape[0]) #获得行数,返回 2
print(a.shape[1]) #获得列数,返回 5

 



 矩阵的截取

 按行列截取

矩阵的截取和list相同,可以通过[](方括号)来截取

复制代码
import numpy as np
a = np.array([[1,2,3,4,5],[6,7,8,9,10]])

print(a[0:1]) #截取第一行,返回 [[1 2 3 4 5]]
print(a[1,2:5]) #截取第二行,第三、四列,返回 [8 9]

print(a[1,:]) #截取第二行,返回 [ 6  7  8  9 10]
复制代码

 

 按条件截取

按条件截取其实是在[](方括号)中传入自身的布尔语句
例如

复制代码
import numpy as np

a = np.array([[1,2,3,4,5],[6,7,8,9,10]])
b = a[a>6] # 截取矩阵a中大于6的元素,范围的是一维数组
print(b) # 返回 [ 7  8  9 10]

# 其实布尔语句首先生成一个布尔矩阵,将布尔矩阵传入[](方括号)实现截取
print(a>6) 
# 返回
[[False False False False False]
 [False  True  True  True  True]]
复制代码

 

按条件截取应用较多的是对矩阵中满足一定条件的元素变成特定的值。
例如将矩阵中大于6的元素变成0。

复制代码
import numpy as np

a = np.array([[1,2,3,4,5],[6,7,8,9,10]])
print(a)
#开始矩阵为
[[ 1  2  3  4  5]
 [ 6  7  8  9 10]]

a[a>6] = 0
print(a)
#大于6清零后矩阵为
[[1 2 3 4 5]
 [6 0 0 0 0]]
复制代码

 


 矩阵的合并

矩阵的合并可以通过numpy中的hstack方法和vstack方法实现

复制代码
import numpy as np

a1 = np.array([[1,2],[3,4]])
a2 = np.array([[5,6],[7,8]])

#!注意 参数传入时要以列表list或元组tuple的形式传入
print(np.hstack([a1,a2])) 
#横向合并,返回结果如下 
[[1 2 5 6]
 [3 4 7 8]]

print(np.vstack((a1,a2)))
#纵向合并,返回结果如下
[[1 2]
 [3 4]
 [5 6]
 [7 8]]
复制代码

矩阵的合并也可以通过concatenatef方法。

np.concatenate( (a1,a2), axis=0 )  等价于  np.vstack( (a1,a2) )

np.concatenate( (a1,a2), axis=1 )  等价于  np.hstack( (a1,a2) )


 通过函数创建矩阵

numpy模块中自带了一些创建ndarray对象的函数,可以很方便的创建常用的或有规律的矩阵。

arange

复制代码
import numpy as np

a = np.arange(10) # 默认从0开始到10(不包括10),步长为1
print(a) # 返回 [0 1 2 3 4 5 6 7 8 9]

a1 = np.arange(5,10) # 从5开始到10(不包括10),步长为1
print(a1) # 返回 [5 6 7 8 9]

a2 = np.arange(5,20,2) # 从5开始到20(不包括20),步长为2
print(a2) # 返回 [ 5  7  9 11 13 15 17 19]
复制代码

 

 linspace

linspace()和matlab的linspace很类似,用于创建指定数量等间隔的序列,实际生成一个等差数列。

import numpy as np

a = np.linspace(0,10,7) # 生成首位是0,末位是10,含7个数的等差数列
print(a) 
# 结果 
[  0.           1.66666667   3.33333333   5.         6.66666667  8.33333333  10.        ]

 

 logspace

linspace用于生成等差数列,而logspace用于生成等比数列。
下面的例子用于生成首位是100,末位是102,含5个数的等比数列。

import numpy as np

a = np.logspace(0,2,5)
print(a)
# 结果
[   1.      3.16227766   10.           31.6227766   100.  ]

 ones、zeros、eye、empty

ones创建全1矩阵
zeros创建全0矩阵
eye创建单位矩阵
empty创建空矩阵(实际有值)

复制代码
import numpy as np

a_ones = np.ones((3,4)) # 创建3*4的全1矩阵
print(a_ones)
# 结果
[[ 1.  1.  1.  1.]
 [ 1.  1.  1.  1.]
 [ 1.  1.  1.  1.]]

a_zeros = np.zeros((3,4)) # 创建3*4的全0矩阵
print(a_zeros)
# 结果
[[ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]]

a_eye = np.eye(3) # 创建3阶单位矩阵
print(a_eye)
# 结果
[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]

a_empty = np.empty((3,4)) # 创建3*4的空矩阵 
print(a_empty)
# 结果
[[  1.78006111e-306  -3.13259416e-294   4.71524461e-309   1.94927842e+289]
 [  2.10230387e-309   5.42870216e+294   6.73606381e-310   3.82265219e-297]
 [  6.24242356e-309   1.07034394e-296   2.12687797e+183   6.88703165e-315]]
复制代码

 fromstring

fromstring()方法可以将字符串转化成ndarray对象,需要将字符串数字化时这个方法比较有用,可以获得字符串的ascii码序列。

a = "abcdef"
b = np.fromstring(a,dtype=np.int8) # 因为一个字符为8为,所以指定dtype为np.int8
print(b) # 返回 [ 97  98  99 100 101 102]

 

 fromfunction

fromfunction()方法可以根据矩阵的行号列号生成矩阵的元素。
例如创建一个矩阵,矩阵中的每个元素都为行号和列号的和。

复制代码
import numpy as np

def func(i,j): 
    return i+j

a = np.fromfunction(func,(5,6)) 
# 第一个参数为指定函数,第二个参数为列表list或元组tuple,说明矩阵的大小
print(a)
# 返回
[[ 0.  1.  2.  3.  4.  5.]
 [ 1.  2.  3.  4.  5.  6.]
 [ 2.  3.  4.  5.  6.  7.]
 [ 3.  4.  5.  6.  7.  8.]
 [ 4.  5.  6.  7.  8.  9.]]
#注意这里行号的列号都是从0开始的
复制代码

 


 矩阵的运算

 常用矩阵运算符

numpy中的ndarray对象重载了许多运算符,使用这些运算符可以完成矩阵间对应元素的运算。

运算符 说明
+ 矩阵对应元素相加
矩阵对应元素相减
* 矩阵对应元素相乘
/ 矩阵对应元素相除,如果都是整数则取商
% 矩阵对应元素相除后取余数
** 矩阵每个元素都取n次方,如**2:每个元素都取平方

例如

复制代码
import numpy as np
a1 = np.array([[4,5,6],[1,2,3]])
a2 = np.array([[6,5,4],[3,2,1]])

print(a1+a2) # 相加
# 结果
[[10 10 10]
 [ 4  4  4]]

print(a1/a2) # 整数相除取商
# 结果
[[0 1 1]
 [0 1 3]]

print(a1%a2) # 相除取余数
# 结果
[[4 0 2]
 [1 0 0]]
复制代码

 


 常用矩阵函数

同样地,numpy中也定义了许多函数,使用这些函数可以将函数作用于矩阵中的每个元素。
表格中默认导入了numpy模块,即 import numpy as np

a为ndarray对象。

矩阵函数 说明
np.sin(a) 对矩阵a中每个元素取正弦,sin(x)
np.cos(a) 对矩阵a中每个元素取余弦,cos(x)
np.tan(a) 对矩阵a中每个元素取正切,tan(x)
np.arcsin(a) 对矩阵a中每个元素取反正弦,arcsin(x)
np.arccos(a) 对矩阵a中每个元素取反余弦,arccos(x)
np.arctan(a) 对矩阵a中每个元素取反正切,arctan(x)
np.exp(a) 对矩阵a中每个元素取指数函数,ex
np.sqrt(a) 对矩阵a中每个元素开根号√x

例如

复制代码
import numpy as np

a = np.array([[1,2,3],[4,5,6]])
print(np.sin(a))
# 结果
[[ 0.84147098  0.90929743  0.14112001]
 [-0.7568025  -0.95892427 -0.2794155 ]]

print(np.arcsin(a))
# 结果
C:\Users\Administrator\Desktop\learn.py:6: RuntimeWarning: invalid value encountered in arcsin
  print(np.arcsin(a))
[[ 1.57079633         nan         nan]
 [        nan         nan         nan]]
复制代码

当矩阵中的元素不在定义域范围内,会产生RuntimeWarning,结果为nan(not a number)。

 


  矩阵乘法(点乘)

矩阵乘法必须满足矩阵乘法的条件,即第一个矩阵的列数等于第二个矩阵的行数。
矩阵乘法的函数为 dot
例如

复制代码
import numpy as np

a1 = np.array([[1,2,3],[4,5,6]]) # a1为2*3矩阵
a2 = np.array([[1,2],[3,4],[5,6]]) # a2为3*2矩阵

print(a1.shape[1]==a2.shape[0]) # True, 满足矩阵乘法条件
print(a1.dot(a2)) 
# a1.dot(a2)相当于matlab中的a1*a2
# 而python中的a1*a2相当于matlab中的a1.*a2
# 结果
[[22 28]
 [49 64]]
复制代码

 


 矩阵的转置

复制代码
import numpy as np

a = np.array([[1,2,3],[4,5,6]])

print(a.transpose())
# 结果
[[1 4]
 [2 5]
 [3 6]]
复制代码

矩阵的转置还有更简单的方法,就是a.T

复制代码
import numpy as np

a = np.array([[1,2,3],[4,5,6]])
print(a.T)
# 结果
[[1 4]
 [2 5]
 [3 6]]
复制代码

 


 矩阵的逆

求矩阵的逆需要先导入numpy.linalg,用linalg的inv函数来求逆。
矩阵求逆的条件是矩阵的行数和列数相同。

复制代码
import numpy as np
import numpy.linalg as lg

a = np.array([[1,2,3],[4,5,6],[7,8,9]])

print(lg.inv(a))
# 结果
[[ -4.50359963e+15   9.00719925e+15  -4.50359963e+15]
 [  9.00719925e+15  -1.80143985e+16   9.00719925e+15]
 [ -4.50359963e+15   9.00719925e+15  -4.50359963e+15]]

a = np.eye(3) # 3阶单位矩阵
print(lg.inv(a)) # 单位矩阵的逆为他本身
# 结果
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]
复制代码

 


  矩阵信息获取(如平均值)

 最大最小值

获得矩阵中元素最大最小值的函数分别是maxmin,可以获得整个矩阵、行或列的最大最小值。
例如

复制代码
import numpy as np

a = np.array([[1,2,3],[4,5,6]])
print(a.max()) #获取整个矩阵的最大值 结果: 6
print(a.min()) #结果:1

# 可以指定关键字参数axis来获得行最大(小)值或列最大(小)值
# axis=0 行方向最大(小)值,即获得每列的最大(小)值
# axis=1 列方向最大(小)值,即获得每行的最大(小)值
# 例如

print(a.max(axis=0))
# 结果为 [4 5 6]

print(a.max(axis=1))
# 结果为 [3 6]

# 要想获得最大最小值元素所在的位置,可以通过argmax函数来获得
print(a.argmax(axis=1))
# 结果为 [2 2]
复制代码

 

 平均值

获得矩阵中元素的平均值可以通过函数mean()。同样地,可以获得整个矩阵、行或列的平均值。

复制代码
import numpy as np

a = np.array([[1,2,3],[4,5,6]])
print(a.mean()) #结果为: 3.5

# 同样地,可以通过关键字axis参数指定沿哪个方向获取平均值
print(a.mean(axis=0)) # 结果 [ 2.5  3.5  4.5]
print(a.mean(axis=1)) # 结果 [ 2.  5.]
复制代码

 

 方差

方差的函数为var(),方差函数var()相当于函数mean(abs(x - x.mean())**2),其中x为矩阵。

复制代码
import numpy as np

a = np.array([[1,2,3],[4,5,6]])
print(a.var()) # 结果 2.91666666667

print(a.var(axis=0)) # 结果 [ 2.25  2.25  2.25]
print(a.var(axis=1)) # 结果 [ 0.66666667  0.66666667]
复制代码

 

 标准差

标准差的函数为std()
std()相当于sqrt(mean(abs(x - x.mean())**2)),或相当于sqrt(x.var())

复制代码
import numpy as np

a = np.array([[1,2,3],[4,5,6]])
print(a.std()) # 结果 1.70782512766

print(a.std(axis=0)) # 结果 [ 1.5  1.5  1.5]
print(a.std(axis=1)) # 结果 [ 0.81649658  0.81649658]
复制代码

 


 

 中值

中值指的是将序列按大小顺序排列后,排在中间的那个值,如果有偶数个数,则是排在中间两个数的平均值。

例如序列[5,2,6,4,2],按大小顺序排成 [2,2,4,5,6],排在中间的数是4,所以这个序列的中值是4。

又如序列[5,2,6,4,3,2],按大小顺序排成 [2,2,3,4,5,6],因为有偶数个数,排在中间两个数是3、4,所以这个序列中值是3.5。

中值的函数是median(),调用方法为numpy.median(x,[axis]),axis可指定轴方向,默认axis=None,对所有数去中值。

复制代码
import numpy as np
x = np.array([[1,2,3],[4,5,6]])

print(np.median(x))  # 对所有数取中值
# 结果
3.5

print(np.median(x,axis=0))  # 沿第一维方向取中值
# 结果
[ 2.5  3.5  4.5]

print(np.median(x,axis=1))  # 沿第二维方向取中值
# 结果
[ 2.  5.]
复制代码

求和

矩阵求和的函数是sum(),可以对行,列,或整个矩阵求和

复制代码
import numpy as np

a = np.array([[1,2,3],[4,5,6]])

print(a.sum())           # 对整个矩阵求和
# 结果 21

print(a.sum(axis=0)) # 对行方向求和
# 结果 [5 7 9]

print(a.sum(axis=1)) # 对列方向求和
# 结果 [ 6 15]
复制代码

 

累积和

某位置累积和指的是该位置之前(包括该位置)所有元素的和。

例如序列[1,2,3,4,5],其累计和为[1,3,6,10,15],即第一个元素为1,第二个元素为1+2=3,……,第五个元素为1+2+3+4+5=15。

矩阵求累积和的函数是cumsum(),可以对行,列,或整个矩阵求累积和。

复制代码
import numpy as np

a = np.array([[1,2,3],[4,5,6]])

print(a.cumsum())            # 对整个矩阵求累积和
# 结果 [ 1  3  6 10 15 21]

print(a.cumsum(axis=0))  # 对行方向求累积和
# 结果
[[1 2 3]
 [5 7 9]]

print(a.cumsum(axis=1))  # 对列方向求累积和
# 结果
[[ 1  3  6]
 [ 4  9 15]]

转自:https://blog.csdn.net/jacke121/article/details/76146884

(转)神经网络激活函数sigmoid relu tanh 为什么sigmoid 容易梯度消失

转自:https://blog.csdn.net/DanyHgc/article/details/73850546

  1. 什么是激活函数
  2. 为什么要用
  3. 都有什么
  4. sigmoid ,ReLU, softmax 的比较
  5. 如何选择

1. 什么是激活函数

如下图,在神经元中,输入的 inputs 通过加权,求和后,还被作用了一个函数,这个函数就是激活函数 Activation Function。


2. 为什么要用

如果不用激励函数,每一层输出都是上层输入的线性函数,无论神经网络有多少层,输出都是输入的线性组合。
如果使用的话,激活函数给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。


3. 都有什么

(1) sigmoid函数

公式:

曲线:

也叫 Logistic 函数,用于隐层神经元输出
取值范围为(0,1)
它可以将一个实数映射到(0,1)的区间,可以用来做二分类。
在特征相差比较复杂或是相差不是特别大时效果比较好。

sigmoid缺点:
激活函数计算量大,反向传播求误差梯度时,求导涉及除法
反向传播时,很容易就会出现梯度消失的情况,从而无法完成深层网络的训练

下面解释为何会出现梯度消失:

反向传播算法中,要对激活函数求导,sigmoid 的导数表达式为:

sigmoid 原函数及导数图形如下:

由图可知,导数从 0 开始很快就又趋近于 0 了,易造成“梯度消失”现象

(2) Tanh函数

公式

曲线

也称为双切正切函数
取值范围为[-1,1]。
tanh在特征相差明显时的效果会很好,在循环过程中会不断扩大特征效果。
与 sigmoid 的区别是,tanh 是 0 均值的,因此实际应用中 tanh 会比 sigmoid 更好

(3) ReLU

Rectified Linear Unit(ReLU) – 用于隐层神经元输出

公式

曲线

输入信号 <0 时,输出都是0,>0 的情况下,输出等于输入

ReLU 的优点:
Krizhevsky et al. 发现使用 ReLU 得到的 SGD 的收敛速度会比 sigmoid/tanh 快很多

ReLU 的缺点:
训练的时候很”脆弱”,很容易就”die”了
例如,一个非常大的梯度流过一个 ReLU 神经元,更新过参数之后,这个神经元再也不会对任何数据有激活现象了,那么这个神经元的梯度就永远都会是 0.
如果 learning rate 很大,那么很有可能网络中的 40% 的神经元都”dead”了。

(4) softmax函数

Softmax – 用于多分类神经网络输出

公式

举个例子来看公式的意思:

就是如果某一个 zj 大过其他 z, 那这个映射的分量就逼近于 1,其他就逼近于 0,主要应用就是多分类。

为什么要取指数,第一个原因是要模拟 max 的行为,所以要让大的更大。
第二个原因是需要一个可导的函数。


4. sigmoid ,ReLU, softmax 的比较

Sigmoid 和 ReLU 比较:

sigmoid 的梯度消失问题,ReLU 的导数就不存在这样的问题,它的导数表达式如下:

曲线如图

对比sigmoid类函数主要变化是:
1)单侧抑制
2)相对宽阔的兴奋边界
3)稀疏激活性。

Sigmoid 和 Softmax 区别:

softmax is a generalization of logistic function that “squashes”(maps) a K-dimensional vector z of arbitrary real values to a K-dimensional vector σ(z) of real values in the range (0, 1) that add up to 1.

sigmoid将一个real value映射到(0,1)的区间,用来做二分类。

而 softmax 把一个 k 维的real value向量(a1,a2,a3,a4….)映射成一个(b1,b2,b3,b4….)其中 bi 是一个 0~1 的常数,输出神经元之和为 1.0,所以相当于概率值,然后可以根据 bi 的概率大小来进行多分类的任务。

二分类问题时 sigmoid 和 softmax 是一样的,求的都是 cross entropy loss,而 softmax 可以用于多分类问题

softmax是sigmoid的扩展,因为,当类别数 k=2 时,softmax 回归退化为 logistic 回归。具体地说,当 k=2 时,softmax 回归的假设函数为:

利用softmax回归参数冗余的特点,从两个参数向量中都减去向量θ1 ,得到:

最后,用 θ′ 来表示 θ2−θ1,上述公式可以表示为 softmax 回归器预测其中一个类别的概率为

另一个类别概率的为

这与 logistic回归是一致的。

softmax建模使用的分布是多项式分布,而logistic则基于伯努利分布

多个logistic回归通过叠加也同样可以实现多分类的效果,但是 softmax回归进行的多分类,类与类之间是互斥的,即一个输入只能被归为一类;多个logistic回归进行多分类,输出的类别并不是互斥的,即”苹果”这个词语既属于”水果”类也属于”3C”类别。


5. 如何选择

选择的时候,就是根据各个函数的优缺点来配置,例如:

如果使用 ReLU,要小心设置 learning rate,注意不要让网络出现很多 “dead” 神经元,如果不好解决,可以试试 Leaky ReLU、PReLU 或者 Maxout.


From: https://blog.csdn.net/DanyHgc/article/details/73850546