文章目录

  • 1 pycharm查看函数信息
  • 3线性回归程序
  • 4理解卷积神经网络中的通道
  • 5 mnist分类
  • 6 实验:使用卷积递归神经网络进行单通道和多通道声音事件检测。
    • 6.1 遇到的问题:
      • 6.1.1 ImportError: No module named 通用解决方法
      • 6.1.2 keras之多GPU训练方法
      • 6.1.3 Tensorflow在Pycharm中报错 :找不到 libcublas.so.9.0
      • 6.1.4 import librosa时出问题
      • 6.1.5 安装cudnn等包的另一种方法
      • 6.1.6 设置时设的是GPU运行,但实际上CPU在跑而GPU不跑
      • 6.1.7 找不到enum
    • 6.2 『开发技术』GPU训练加速原理
    • 6.3 batch size设置技巧
      • 6.3.1 mini-batch的几个好处 :
      • 6.3.2批量选择方法
  • 7 tensorflow2.0学习
    • 7.1 概述
    • 7.2 Modules
    • 7.3 Class
    • 7.4 Functions
      • 7.4.1 tensor操作
        • (1) tensor和numpy的转化
        • (2) tf.transpose()
        • (3)expand_dim()增加维度
        • (4)tf.reshape重塑张量
        • (5)打印Tensor的值
        • (6)降低维度reduce系列
        • (7)矩阵运算
        • (8)tf.assign()
      • 7.4.2 模型与层的操作
        • (1) tf.keras.Input()
        • (2) 获取模型某一层权重get_weights()
        • (3)模型权重的保存和加载
        • (4)模型保存和加载
        • (5)model.summary()需要注意的地方
        • (6)TimeDistributed(Dense)和Dense()层具有相同的结果(在某些情况下)
      • 7.4.3 模型训练
        • (1)回调函数Callbacks
    • 7.5 构建高级模型
      • 7.5.1模型子类化
      • 7.5.2 自定义层
    • 7.6 tensorflow2张量的数学运算
  • 8 python学习
    • 8.1 python方法
      • 8.1.1 python字符串格式化方法——format函数
      • 8.1.2 for循环中常用的——enumerate() 函数
    • 8.2 numpy的方法
      • 8.2.1 np.linalg.norm(求范数)
      • 8.2.2 数组拼接
      • 8.2.3 数组复制的坑——np.copy()
      • 8.2.4 获得数组的最大、小值索引
      • 8.2.5 np.unique( )去除数组中的重复数字
      • 8.2.6 reshape的坑——IndexError: invalid index to scalar variable.
      • 8.2.7 np.where()——获取数组中指定元素的索引位置
  • 9 音频处理
    • 9.1 ffmpeg用法
      • 9.1.1 剪切音视频
      • 9.1.2 从视频中提取音频
    • 9.2 librosa
      • 9.2.1 librosa遇到的坑
  • 10 声学事件检测
    • 10.1 检测指标(TP,FP,TN,FN,精确率召回率等直观图)

1 pycharm查看函数信息

按住ctrl键,将鼠标放到函数上,就会显示函数信息,点击进去可以查看函数源码。

3线性回归程序

要点:** y = model.predict(x_data)#预测输出** ** w,b = model.layers [0] .get_weights()#显示模型参数**

4理解卷积神经网络中的通道

在深度学习的算法学习中,都会提到channel这个概念。在一般的深度学习框架的conv2d中,如tensorflow,mxnet,通道都是必填的一个参数。

该如何理解?先看一看不同框架中的解释文档。

首先,是 tensorflow 中给出的,对于输入样本中 channels 的含义。一般的RGB图片,channels 数量是 3 (红、绿、蓝);而monochrome图片,channels 数量是 1 。

为了更直观的理解,下面举个例子,图片使用自 吴恩达老师的深度学习课程 。

如下图,假设现有一个为 6×6×36×6×3 的图片样本,使用 3×3×33×3×3 的卷积核(filter)进行卷积操作。此时输入图片的 channels 为 33 ,而卷积核中的 in_channels 与 需要进行卷积操作的数据的 channels 一致(这里就是图片样本,为3)。

接下来,进行卷积操作,卷积核中的27个数字与分别与样本对应相乘后,再进行求和,得到第一个结果。依次进行,最终得到 4×4 的结果。

上面步骤完成后,由于只有一个卷积核,所以最终得到的结果为 4×4×1 , out_channels 为 11 。

在实际应用中,都会使用多个卷积核。这里如果再加一个卷积核,就会得到 4×4×2的结果。

总结一下,把上面提到的 channels 分为三种:

1 最初输入的图片样本的 channels ,取决于图片类型,比如RGB;
2 卷积操作完成后输出的 out_channels取决于卷积核的数量此时的 out_channels 也会作为下一次卷积时的卷积核的 in_channels
3 卷积核中的 in_channels ,刚刚2中已经说了,就是上一次卷积的 out_channels ,如果是第一次做卷积,就是1中样本图片的 channels 。

eg:
tf.nn.conv2d(input, filter, strides, padding, use_cudnn_on_gpu = None, name = None)

第二个参数filter:

CNN卷积网络中的卷积核,要求是一个Tensor,类型和input类型相同,shape为[filter_height, filter_width, in_channels, out_channels]:

filter_height:卷积核的高度
filter_width:卷积核的宽度
in_channels:图像的通道数,input的in_channels相同
out_channels:卷积核的个数

5 mnist分类

import numpy as np
from keras.models import Sequential
from keras.layers.core import Dense, Dropout,Activation
from keras.layers import Conv2D, MaxPool2D, Flatten
from keras.optimizers import Adam
from keras.utils import np_utils
from keras.datasets import mnistdef load_data():path = 'f://mnist//mnist.npz'f = np.load(path)                       #导入数据(x_train, y_train), (x_test, y_test) = (f['x_train'],f['y_train']),(f['x_test'],f['y_test'])#x_train, y_train = f['x_train'],f['y_train']#x_test, y_test = f['x_test'],f['y_test']number = 60000x_train = x_train[0:number]y_train = y_train[0:number]x_train = x_train.reshape(number, 28*28)x_test = x_test.reshape(x_test.shape[0], 28*28)x_train = x_train.astype('float32')            #类型转换x_test = x_test.astype('float32')y_train = np_utils.to_categorical(y_train,10)   #转化为独热码y_test = np_utils.to_categorical(y_test,10)x_train = x_train.reshape(-1,28,28,1)/255       #最后的那个1表示通道数,必须有x_test = x_test.reshape(-1,28,28,1)/255return (x_train, y_train),(x_test,y_test)(x_train, y_train), (x_test,y_test) = load_data()model = Sequential()
model.add(Conv2D(input_shape=(28,28,1),filters=32,kernel_size=5,strides=1,padding='same',activation='relu'))
model.add(MaxPool2D(pool_size=2,strides=2,padding='same'))
model.add(Conv2D(kernel_size=5,filters=64,strides=1,padding='same',activation='relu'))
model.add(MaxPool2D(pool_size=2,strides=2,padding='same'))
model.add(Flatten())
model.add(Dense(units=1024,activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(units=10,activation='softmax'))model.compile(loss='categorical_crossentropy',optimizer=Adam(lr=1e-4),metrics=['accuracy'])     #metrics计算准确率
model.fit(x_train,y_train,batch_size=64,epochs=10)loss,acc = model.evaluate(x_test,y_test)print('\nTest loss:',loss)
print('\nTest acc:',acc)

注意:loss,acc = model.evaluate(x_test,y_test) #在测试集测试准确率

model = load_model('model.h5')    #载入模型model.fit(x_train,y_train,batch_size=64,epochs=1)  #继续训练

6 实验:使用卷积递归神经网络进行单通道和多通道声音事件检测。

   DCASE 2017真实声音事件检测获胜方法

6.1 遇到的问题:

6.1.1 ImportError: No module named 通用解决方法

问题原因:
(1)该模块没有安装
(2)该模块已经安装,但是没有安装到python的搜索路径下
解决方案:
(1)如果是上面的原因1导致的,这个没什么说的,具体安装就行了,最常用安装方法:使用pip install 安装;
(2)如果是上面的原因2导致的。解决方法:将刚刚安装完的包,添加到Python添加默认模块搜索路径就行了。

方法②: 增加.pth文件【推荐】
在site-packages添加一个路径文件(假设你现在的python默认是:/usr/local/lib/python2.7/),
在 /usr/local/lib/python2.7/site-packages 路径下 新建一个文件 “mypkpath.pth”,文件里面的内容是 你想要加入的模块文件所在的目录名称。
例如:
新建文件:/usr/local/lib/python2.7/site-packages/mypkpath.pth
该文件内容:/usr/lib/python2.6/site-packages/

6.1.2 keras之多GPU训练方法

将模型在多个GPU上复制

特别地,该函数用于单机多卡的数据并行支持,它按照下面的方式工作:
(1)将模型的输入分为多个子batch
(2)在每个设备上调用各自的模型,对各自的数据集运行
(3)将结果连接为一个大的batch(在CPU上)
例子:

from keras.utils import multi_gpu_model# 将 `model` 复制到 8 个 GPU 上。
# 假定你的机器有 8 个可用的 GPU。
parallel_model = multi_gpu_model(model, gpus=2)
parallel_model.compile(loss='categorical_crossentropy',optimizer='rmsprop')# 这个 `fit` 调用将分布在 8 个 GPU 上。
# 由于 batch size 为 256,每个 GPU 将处理 32 个样本。
parallel_model.fit(x, y, epochs=20, batch_size=256)

表示使用两块GPU
如果想指定使用哪两块GPU,可以在开头添加如下语句

import os
os.environ["CUDA_VISIBLE_DEVICES"] = "2,3"

注意
1)multi_gpu_model这个函数一定要放对位置,放在compile之前
2)若报错为:

TypeError: can’t pickle module objects

解决方法如下:

意思就是直接使用传入方法keras.utils.multi_gpu_model(model, gpus)中的model即可,而不要使用返回的parallel_model,即:

model.save('xxx.h5')
6.1.3 Tensorflow在Pycharm中报错 :找不到 libcublas.so.9.0

Pycharm中显示 :ImportError: libcublas.so.9.0: cannot open shared object file: No such file
可能原因,CUDA版本不对,安装对应版本的CUDA;如果匹配却仍然报错,那是因为cuda环境变量配置有误,pycharm找不到
解决办法:
1)在Pycharm中添加环境变量 ,右上角倒三角下拉,进入菜单Edit configurations,
2)打开重新添加环境变量 :Environment variables 那栏
3)增加:PYTHONUNBUFFERED=1; LD_LIBRARY_PATH=/usr/local/cuda-9.0/lib64;usr/local/lib
注:/usr/local/cuda-9.0/lib64需要改为在用户下cuda9的路径,系统的是cuda8,不兼容。即改为/data/guanyadong/cuda9/lib64,其他不用改

添加成功以后就可以正常运行了。这种方法的坏处是,每次新建文件,都需要手动添加环境变量。

6.1.4 import librosa时出问题

6.1.5 安装cudnn等包的另一种方法


点里面的+,搜索cudnn,等一会右下角会有特定版本的选择,这样安装多简单。

6.1.6 设置时设的是GPU运行,但实际上CPU在跑而GPU不跑

原因:可能cuda或cudnn有问题,所以只能使用CPU运行
先把tensorflow删了只留tensorflow-gpu(用6.1.5类似的方法),然后看能不能GPU运行,如果有bug提示是cudnn或者cuda的问题就好解决了,具体方法上面都说了。

6.1.7 找不到enum

原因:(1)enum改名成了enum34,有些比较老的代码还用的enum;
(2)安装了enum34以后pycharm还是找不到,先看下enum34的安装路径
看到安装路径就明白了,在虚拟环境py2.7下用pip居然安装到了基本环境即python3.7中(好神奇的说),所以在py27的虚拟环境中当然找不到了,解决方法:参照6.1.1,添加路径

6.2 『开发技术』GPU训练加速原理

GPU是如何加速的呢?

我打算从两个方面来解答:

单个GPU较于CPU加速:
在训练网络中,其实大量的运算资源都消耗在了数值计算上面,大部分网络训练的过程都是1.计算loss,2.根据loss求梯度,3.再根据梯度更新参数(梯度下降原理)。无论在GPU还是CPU中,都是不断重复123步。但是由于CPU是通用计算单元(并不擅长数值运行),而GPU特长是图像处理(数值计算)。所以GPU更加适合训练网络,从而起到加速效果。

多GPU较于单GPU加速:
一般在GPU训练中,同一个GPU中,batch_size的大小,决定训练的速度,batch_size越小,训练一轮所需的步数(data_len/batch_size)就会越大,从而花费时间越多

多GPU数据并行加速原理:

假设一台机器上有k块GPU。给定需要训练的模型,每块GPU及其相应的显存将分别独立维护一份完整的模型参数。在模型训练的任意一次迭代中,给定一个随机小批量,我们将该批量中的样本划分成k份并分给每块显卡的显存一份。然后,每块GPU将根据相应显存所分到的小批量子集和所维护的模型参数分别计算模型参数的本地梯度。接下来,我们把k块显卡的显存上的本地梯度相加,便得到当前的小批量随机梯度。之后,每块GPU都使用这个小批量随机梯度分别更新相应显存所维护的那一份完整的模型参数。下图描绘了使用2块GPU的数据并行下的小批量随机梯度的计算。

使用2块GPU的数据并行下的小批量随机梯度的计算

我们回忆下梯度下降的过程,1.计算loss,2.根据loss求梯度,3.再根据梯度更新参数。

使用上述的多GPU数据并行方法,可以理解为把batch_size扩大了k倍,从而总的时间缩短为了k分之1,实现了多GPU计算训练。
其实每一个GPU上网络的参数都是相同的,因为都是从相同的loss做的更新。
假设单GPU和k个GPU的batch size相同,那么,单GPU一次epoch迭代的次数是多GPU的k倍,即单GPU更新参数的次数多。因此不能简单的认为多GPU和单GPU收敛到相同程度时,多GPU的收敛时间是单GPU收敛时间的k分之1

多GPU加速适用于数据量大的情况,假如本身程序用一个GPU都用不满,若强行分给多个GPU,训练速度会反而更慢(因为GPU之间传输信息的时间也是比较长的)

6.3 batch size设置技巧

样本量少的时候会带来很大的方差,而这个大方差恰好会导致梯度下降到很差的局部最优点(只是微微凸下去的最优点)和鞍点的时候不稳定,一不小心就因为一个大噪声的到来导致炸出了局部最优点。
与之相反的,当样本量很多时,方差很小,对梯度的估计要准确和稳定的多,因此反而在差劲的局部最优点和鞍点时反而容易自信的呆着不走了,从而导致神经网络收敛到很差的点上,跟出了bug一样的差劲。

batch的size设置的不能太大也不能太小,因此实际工程中最常用的就是mini-batch,一般size设置为几十或者几百。

GPU对2的幂次的batch可以发挥更佳的性能,因此设置成16、32、64、128…时往往要比设置为整10、整100的倍数时表现更优

6.3.1 mini-batch的几个好处 :

(1)提高了运行效率,相比batch-GD的每个epoch只更新一次参数,使用mini-batch可以在一个epoch中多次更新参数,加速收敛。
(2)解决了某些任务中,训练集过大,无法一次性读入内存的问题。
(3)虽然第一点是mini-batch提出的最初始的原因,但是后来人们发现,使用mini-batch还有个好处,即每次更新时由于没有使用全量数据而仅仅使用batch内数据,从而人为给训练带来了噪声,而这个操作却往往能够带领算法走出局部最优(鞍点)。理论证明参见COLT的这篇论文Escaping From Saddle Points-Online Stochastic Gradient for Tensor Decomposition。也就是说,曾经我们使用mini-batch主要是为了加快收敛和节省内存,同时也带来每次更新有些“不准”的副作用,但是现在的观点来看,这些“副作用”反而对我们的训练有着更多的增益,也变成mini-batch技术最主要的优点。

总结下来:批量大小过小,花费时间多,同时渐变震荡严重,不利于收敛;批量大小过大,不同程度的梯度方向没有任何变化,容易放置局部极小值

6.3.2批量选择方法

(1)当有足够的算力时,替换批量大小为32英寸小一些。(2)算力不够时,在效率和泛化性之间做折衷,尽量选择更小的批量大小。(3)当模型训练到尾声,想更精细化地提高成绩(某种论文实验/比赛到最后),有一个有用的技巧,就是设置批处理大小为1,即做纯SGD,慢慢把错误磨低。

7 tensorflow2.0学习

7.1 概述

在Keras API中总共有如下三大块:

在Modules中有构建训练模型各种必备的组件,如激活函数activations、损失函数losses、优化器optimizers等;在Class中有Sequential和Model两个类,它们用来堆叠模型;在Functions中有Input()函数,它用来实例化张量。

7.2 Modules

Modules中有activations、losses、optimizers等构建训练模型时各种必备的组件。下图就是Modules中有所的模块。

下面我们详细说说里面最常见的几个模块应该如何使用。

  1. 常用的数据集(datasets)

在TensorFlow2.0中,常用的数据集需要使用tf.keras.datasets来加载,在datasets中有如下数据集。


数据集我们可以像下面这样加载

(train_images,train_labels),(test_images,test_labels)= keras.datasets.fashion_mnist.load_data()

当然我们平时使用的数据集肯定不在于此,这些数据集都是些最基础的数据集。

  1. 神经网络层(Layers)

在构建深度学习网络模型时,我们需要定制各种各样的层结构。这时候就要用到layers了,下图是TensorFlow2.0中部分层,它们都是Layer的子类。


那么我们如何使用layer来构建模型呢?方法如下:

from tensorflow.keras import layers
layers.Conv2D()
layers.MaxPool2D()
layers.Flatten()
layers.Dense()
  1. 激活函数(Optimizers)

在构建深度学习网络时,我们经常需要选择激活函数来使网络的表达能力更强。下面将介绍TensorFlow2.0中的激活函数及它们应该在TensorFlow2.0中该如何使用。下图是TensorFlow2.0中部分激活函数:

from tensorflow.keras import layers
layers.Conv2D(...,activation='relu')
layers.Dense(...,activation='softmax')
  1. 优化器(activations)

通常当我们准备好数据,设计好模型后,我们就需要选择一个合适的优化器(Optimizers)对模型进行优化。下面将介绍TensorFlow2.0中的优化器及他们应该在TensorFlow2.0中该如何使用。下图是TensorFlow2.0中所有的优化器,它们都是Optimizer的子类。


对于优化器的使用你可以像下面这样使用:

optimizers = tf.keras.optimizers.Adam()optimizers = tf.keras.optimizers.SGD()
  1. 损失函数(Losses)

我们知道当我们设计好模型时我们需要优化模型,所谓的优化就是优化网络权值使损失函数值变小,但是损失函数变小是否能代表精度越高呢?那么多的损失函数,我们又该如何选择呢?接下来我们了解下在TensorFlow2.0中如何使用损失函数。下图是TensorFlow2.0中所有的损失函数,它们都是Loss的子类。

对于损失函数的使用你可以像下面这样使用:

loss = tf.keras.losses.SparseCategoricalCrossentropy()loss = tf.keras.losses.mean_squared_error()

7.3 Class

在Class中有Sequential和Model两个类,它们分别是用来堆叠网络层和把堆叠好的层实例化可以训练的模型。

  1. Model

对于实例化Model有下面两种方法

(1).使用keras.Model API

import tensorflow as tfinputs = tf.keras.Input(shape=(3,))x=tf.keras.layers.Dense(4,activation=tf.nn.relu(inputs)outputs=tf.keras.layers.Dense(5, activation=tf.nn.softmax)(x)model=tf.keras.Model(inputs=inputs, outputs=outputs)

(2).继承Model类

import tensorflow as tfclass MyModel(tf.keras.Model):def __init__(self):super(MyModel, self).__init__()self.dense1 = tf.keras.layers.Dense(4, activation=tf.nn.relu)self.dense2 = tf.keras.layers.Dense(5, activation=tf.nn.softmax)def call(self, inputs):x = self.dense1(inputs)return self.dense2(x)model = MyModel()
  1. Sequential

在TensorFlow2.0中,我们可以使用Sequential模型。具体方式如下:

model = keras.Sequential()model = model.add(layers.Conv2D(input_shape=(x_train.shape[1],x_train.shape[2],x_train.shape[3]),filters=32,kernel_size=(3,3), strides=(1,1), padding='valid',activation='relu'))model.add(layers.MaxPool2D(pool_size=(2,2)))model.add(layers.Flatten())model.add(layers.Dense(32,activation='relu'))model.add(layers.Dense(10, activation='softmax'))model.compile(optimizer=keras.optimizers.Adam(),loss=keras.losses.SparseCategoricalCrossentropy(),metrics=['accuracy'])

7.4 Functions

7.4.1 tensor操作
(1) tensor和numpy的转化
A = tf.convert_to_tensor(B)    #numpy->tensor
C = A.numpy()                   #tensor->numpy
(2) tf.transpose()

维度调换,对于二维张量可以理解为转置。多维张量的维度调换多用于图像处理领域

tf.transpose(a,              #a:表示需要变换的张量perm=None,      #perm:a的新的维度序列name='transpose',conjugate=False
)

例子:

import tensorflow as tf
import numpy as npA=np.arange(12).reshape([2,3,2])
X=tf.transpose(A,[0,2,1])
Y=tf.transpose(A,[1,0,2])
with tf.Session() as sess:print("original:")print(A)print("transpose [0,2,1]:")print(sess.run(X))print("transpose [0,2,1]‘s shape:")print(X.get_shape().as_list())print("transpose [1,0,2]:")print(sess.run(Y))print("transpose [1,0,2]'s shape")print(Y.get_shape().as_list())

结果:


original:
[[[ 0  1][ 2  3][ 4  5]][[ 6  7][ 8  9][10 11]]]
transpose [0,2,1]:
[[[ 0  2  4][ 1  3  5]][[ 6  8 10][ 7  9 11]]]
transpose [0,2,1]‘s shape:
[2, 2, 3]
transpose [1,0,2]:
[[[ 0  1][ 6  7]][[ 2  3][ 8  9]][[ 4  5][10 11]]]
transpose [1,0,2]'s shape
[3, 2, 2]
(3)expand_dim()增加维度
# 't' is a tensor of shape [2]
shape(expand_dims(t, 0)) ==> [1, 2]
shape(expand_dims(t, 1)) ==> [2, 1]
shape(expand_dims(t, -1)) ==> [2, 1]# 't2' is a tensor of shape [2, 3, 5]
shape(expand_dims(t2, 0)) ==> [1, 2, 3, 5]
shape(expand_dims(t2, 2)) ==> [2, 3, 1, 5]
shape(expand_dims(t2, 3)) ==> [2, 3, 5, 1]
(4)tf.reshape重塑张量
# tensor 't' is [1, 2, 3, 4, 5, 6, 7, 8, 9]
# tensor 't' has shape [9]
reshape(t, [3, 3]) ==> [[1, 2, 3],[4, 5, 6],[7, 8, 9]]# tensor 't' is [[[1, 1], [2, 2]],
#                [[3, 3], [4, 4]]]
# tensor 't' has shape [2, 2, 2]
reshape(t, [2, 4]) ==> [[1, 1, 2, 2],[3, 3, 4, 4]]
(5)打印Tensor的值
tf.print(a)

注:不可能在没有运行图的情况下检查值。

(6)降低维度reduce系列

和 Numpy 中相应的用法完全一致

# 计算输入 tensor 所有元素的和,或者计算指定的轴所有元素的和
tf.reduce_sum(input_tensor, axis=None, keep_dims=False, name=None)
# 'x' is [[1, 1, 1]
#         [1, 1, 1]]
tf.reduce_sum(x) ==> 6
tf.reduce_sum(x, 0) ==> [2, 2, 2]
tf.reduce_sum(x, 1) ==> [3, 3]
tf.reduce_sum(x, 1, keep_dims=True) ==> [[3], [3]]  # 维度不缩减
tf.reduce_sum(x, [0, 1]) ==> 6# 计算输入 tensor 所有元素的均值/最大值/最小值/积/逻辑与/或
# 或者计算指定的轴所有元素的均值/最大值/最小值/积/逻辑与/或(just like reduce_sum)
tf.reduce_mean(input_tensor, axis=None, keep_dims=False, name=None)
tf.reduce_max(input_tensor, axis=None, keep_dims=False, name=None)
tf.reduce_min(input_tensor, axis=None, keep_dims=False, name=None)
tf.reduce_prod(input_tensor, axis=None, keep_dims=False, name=None)
tf.reduce_all(input_tensor, axis=None, keep_dims=False, name=None)  # 全部满足条件
tf.reduce_any(input_tensor, axis=None, keep_dims=False, name=None) #至少有一个满足条件
(7)矩阵运算

求张量的范数(默认2)

tf.norm(tensor, ord=2, axis=-1, keep_dims=False, name=None)

构建一个单位矩阵

# 构建一个单位矩阵, 或者 batch 个矩阵,batch_shape 以 list 的形式传入
tf.eye(num_rows, num_columns=None, batch_shape=None, dtype=tf.float32, name=None)
# Construct one identity matrix.
tf.eye(2)
==> [[1., 0.],[0., 1.]]
# Construct one 2 x 3 "identity" matrix
tf.eye(2, num_columns=3)
==> [[ 1.,  0.,  0.],[ 0.,  1.,  0.]]
(8)tf.assign()

tf.assign(A, new_number): 这个函数的功能主要是把A的值变为new_number
或 A.assign(new_number)
例如:

import tensorflow as tf;A = tf.Variable(tf.constant(0.0), dtype=tf.float32)
with tf.Session() as sess:sess.run(tf.initialize_all_variables())print sess.run(A)sess.run(tf.assign(A, 10))print sess.run(A)

输出:

0.0
10.0

开始给A赋值为0,经过tf.assign函数后,把A的值变为10

7.4.2 模型与层的操作
(1) tf.keras.Input()

用来实例化Keras张量,用于搭建模型的第一层,有如下参数

tf.keras.Input(shape=None,batch_size=None,name=None,dtype=None,sparse=False,tensor=None, **kwargs)

具体使用方法如下:

x = Input(shape=(32,))
y = Dense(16, activation='softmax')(x)
model = Model(x, y)
(2) 获取模型某一层权重get_weights()

方法一:通过model.get_weights()先获取模型的全部参数(一个列表数组,第一层W,第一层b,第二层W,第二层b,…)。返回模型中所有权重张量的列表,类型为 Numpy 数组。

weights = model.get_weights() #获取整个网络模型的全部参数
print(weights [0].shape)  #第一层的w
print(weights [1].shape)  #第一层的b
print(weights [2].shape)  #第二层的w
print(weights [3].shape)  #第二层的b

方法二:layer.get_weights() :返回层的权重( numpy array)
通过get_layer()函数先获取要获取权重对应的层;接着通过get_weights()

model = load_model('vgg.h5')
layer1 = model.get_layer(index=2)
weights = layer1.get_weights()   #获取该层的参数W和b
(3)模型权重的保存和加载

只保存模型的权重:

model.save_weights('my_model_weights.h5')

如果需要在代码中初始化一个完全相同的模型,请使用:

model.load_weights('my_model_weights.h5')

如果需要加载权重到不同的网络结构(有些层一样)中,例如fine-tune或transfer-learning,可以通过层名字来加载模型:

model.load_weights('my_model_weights.h5', by_name=True)

例如:

"""
假如原模型为:model = Sequential()model.add(Dense(2, input_dim=3, name="dense_1"))model.add(Dense(3, name="dense_2"))...model.save_weights(fname)
"""
# new model
model = Sequential()
model.add(Dense(2, input_dim=3, name="dense_1"))  # will be loaded
model.add(Dense(10, name="new_dense"))  # will not be loaded# load weights from first model; will only affect the first layer, dense_1.
model.load_weights(fname, by_name=True)
(4)模型保存和加载
model.save('my_model.h5')  # creates a HDF5 file 'my_model.h5'model = tf.keras.models.load_model('my_model.h5')

HDF5文件包含:模型的结构;模型的权重;训练配置(损失函数,优化器等);优化器的状态,以便于从上次训练中断的地方开始

(5)model.summary()需要注意的地方

需要先指定input_shape,或者你直接fit一遍它也能自动确定

model.build(input_shape=(None, 448, 448, 3))
model.summary()
(6)TimeDistributed(Dense)和Dense()层具有相同的结果(在某些情况下)

相同效果的情况: keras从版本2.0开始Dense默认仅应用于最后一个维度(例如,如果您应用于Dense(10)具有形状的输入,(n, m, o, p)您将获得具有形状的输出(n, m, o, 10)),因此这种情况下Dense与TimeDistributed(Dense)是等效的。

在其他情况下TimeDistributed(Dense)和Dense()层效果不同。
详情见:Keras 中 TimeDistributed 和 TimeDistributedDense 理解

7.4.3 模型训练
(1)回调函数Callbacks

回调函数是一组在训练的特定阶段被调用的函数集,你可以使用回调函数来观察训练过程中网络内部的状态和统计信息。通过传递回调函数列表到模型的.fit()中,即可在给定的训练阶段调用该函数集中的函数。

【Tips】虽然我们称之为回调“函数”,但事实上Keras的回调函数是一个类,回调函数只是习惯性称呼

keras.callbacks.Callback()

这是回调函数的抽象类,定义新的回调函数必须继承自该类

编写自己的回调函数
我们可以通过继承keras.callbacks.Callback编写自己的回调函数,回调函数通过类成员self.model访问访问,该成员是模型的一个引用。

这里是一个简单的保存每个batch的loss的回调函数:

class LossHistory(keras.callbacks.Callback):    #继承def on_train_begin(self, logs={}):self.losses = []def on_batch_end(self, batch, logs={}):     #重写on_batch_endself.losses.append(logs.get('loss'))
init_lr = 0.1  # 1.0def lr_schedule(epoch):if epoch <= 10:return init_lrelse:return init_lr * 0.85 ** (epoch - 10)lr_schedule = callbacks.LearningRateScheduler(lr_schedule)  #学习率调整early_stopping = callbacks.EarlyStopping(patience=10)       #早停projection = PrototypeProjection(train_gen, freq=4)         #原型投影,频率为4sgd = optimizers.SGD(learning_rate=init_lr, clipnorm=5.0)pnet.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])pnet.fit_generator(train_gen,validation_data=test_gen,epochs=25,callbacks=[early_stopping, lr_schedule, projection],  #callbacksshuffle=False)

7.5 构建高级模型

7.5.1模型子类化

通过对 tf.keras.Model 进行子类化,定义自己的前向传播来构建完全可自定义的模型。
init :创建层并将它们设置为类实例的属性
call: 定义前向传播

class MyModel(tf.keras.Model):def __init__(self, num_classes=10):super(MyModel, self).__init__(name='my_model')self.num_classes = num_classesself.layer1 = layers.Dense(32, activation='relu')      #__init__中建立层self.layer2 = layers.Dense(num_classes, activation='softmax')def call(self, inputs):h1 = self.layer1(inputs)out = self.layer2(h1)return outmodel = MyModel(num_classes=10)
model.compile(optimizer=tf.keras.optimizers.RMSprop(0.001),loss=tf.keras.losses.categorical_crossentropy,metrics=['accuracy'])model.fit(train_x, train_y, batch_size=16, epochs=5)
7.5.2 自定义层

三个函数都是从tf.keras.layers.Layer处继承而来:
init():初始化成员变量;只初始化了输出数据的shape
build():对Layer进行初始化,都初始化了一些成员函数;在call()函数第一次执行时会被调用一次,这时候可以知道输入数据的shape输入数据的shape需要在build()函数中动态获取
call():在该layer被调用时执行。

例子:

class MyDenseLayer(tf.keras.layers.Layer):def __init__(self, num_outputs):super(MyDenseLayer, self).__init__()self.num_outputs = num_outputsdef build(self, input_shape):self.kernel = self.add_variable("kernel",shape=[int(input_shape[-1]),self.num_outputs])def call(self, input):return tf.matmul(input, self.kernel)layer = MyDenseLayer(10)

通过对 tf.keras.layers.Layer 进行子类化并实现以下方法来创建自定义层:

build:创建层的权重。使用 add_weight 方法添加权重。

call:定义前向传播。

import tensorflow as tf
from tensorflow.keras.layers import Layer as KerasLayer ###################from prosenet.ops import distance_matrixclass Prototypes(KerasLayer):                          ####################"""The 'Prototypes Layer' as a tf.keras Layer."""def __init__(self, k, dmin=1.0, Ld=0.01, Lc=0.01, Le=0.1, **kwargs):"""Parameters----------k : intNumber of prototype vectors to create.dmin : float, optionalThreshold to determine whether two prototypes are close, default=1.0.For "diversity" regularization. See paper section 3.2 for details.Ld : float, optionalWeight for "diversity" regularization loss, default=0.01.Lc : float, optionalWeight for "clustering" regularization loss, default=0.01.Le : float, optionalWeight for "evidence" regularization loss, default=0.1.**kwargsAdditional arguments for base `Layer` constructor (name, etc.)"""super(Prototypes, self).__init__(**kwargs)self.k = kself.dmin = dminself.Ld, self.Lc, self.Le = Ld, Lc, Ledef build(self, input_shape):                                     #定义层# Create prototypes as weight variable# NOTE: had to add constraint to keep gradients from explodingself.d = input_shape[-1]# Makes sense to use same `initializer` as LSTM ?self.prototypes = self.add_weight(name='prototypes',shape=(1, self.k, self.d),initializer='glorot_uniform',                         #参数初始化方式constraint=lambda w: tf.clip_by_value(w, -1., 1.),    #约束trainable=True)def call(self, x, training=None):                            # 定义前向传播"""Forward pass."""# L2 distances b/t encodings and prototypesx = tf.expand_dims(x, -2)d2 = tf.norm(x - self.prototypes, ord=2, axis=-1)# Losses only computed `if training`if training:dLoss = self.Ld * self._diversity_term()cLoss = self.Lc * tf.reduce_sum(tf.reduce_min(d2, 0))eLoss = self.Le * tf.reduce_sum(tf.reduce_min(d2, 1))else:dLoss, cLoss, eLoss = 0., 0., 0.self.add_loss(dLoss)self.add_loss(cLoss, inputs=True)self.add_loss(eLoss, inputs=True)# Return exponentially squashed distancesreturn tf.exp(-d2)

7.6 tensorflow2张量的数学运算

参考:TensorFlow2.0:张量的数学运算

8 python学习

8.1 python方法

8.1.1 python字符串格式化方法——format函数

format用法(可以接受不限个参数,位置可以不按顺序
注意:外是引号,内是大括号,.format
例3:设置指定位置,按默认顺序

>>> "{} {}".format("hello","world")
'hello world'

例4:设置指定位置

"{0} {1}".format("hello","world")
'hello world'

例5:设置指定位置

>>> “{1} {0} {1}” .format("hello","world")
>'world hello world'
8.1.2 for循环中常用的——enumerate() 函数

enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。

>>>seq = ['one', 'two', 'three']
>>> for i, element in enumerate(seq):
...     print i, element
...
0 one
1 two
2 three

8.2 numpy的方法

8.2.1 np.linalg.norm(求范数)

1、linalg=linear(线性)+algebra(代数),norm则表示范数。
2、函数参数
x_norm=np.linalg.norm(x, ord=None, axis=None, keepdims=False)
①x: 表示矩阵(也可以是一维)
②ord:范数类型

8.2.2 数组拼接

8.2.3 数组复制的坑——np.copy()

复制数组时一定要用np.copy(),如果直接用等号将旧数组赋值给新数组,那么改变新数组会影响旧数组。

import numpy as np # numpy 数组的复制和 python的list数组的复制是不同的
# 对于python的数组, 可以通过索引,完全复制新的数组
a = [1,2,3,4]
b = a[:]
#这里的 a 和 b是两个完全独立的数组,但是对于numpy并非如此a_np = np.array([1,2,3,4])
b_np = a[:]
a_np[1] = 100
print(a_np)
print(b_np)
print(type(a_np))
print(type(b_np))
# 这里输出的a_np和b_np都是1, 100, 3, 4
# 要想完全复制a_np,要通过调用copy()
# 实际上这里的b_np并不是np数组,而是python的list
c_np = a_np.copy()
a_np[2] = 100
print(a_np)
print(c_np)
print(type(a_np))
print(type(c_np))
# 这里的输出结果是不同的,
# a_np是1, 100, 100, 4
# c_np是1, 100, 3, 4
8.2.4 获得数组的最大、小值索引

**np.unravel_index(a.argmax(), a.shape)**用法:
a.argmax()用于得出数组全局最大值序号;
np.unravel_index()用于将最大值序号转化为坐标。

a = np.array([[1, 2, 3],[4, 5, 6]])
print(a.argmax())                             #最大值是第几个
index = np.unravel_index(a.argmax(), a.shape) #最大值在数组中的位置
print(index)

输出:

5
(1, 2)

对于二维数组:

import numpy as np
a = np.array([[1, 2, 3],[4, 5, 6]])
index = np.unravel_index(a.argmax(), a.shape)
print(index)
>>>(1, 2)

三维数组:

import numpy as np
a = np.array([[[1, 2, 3],[4, 5, 6]]])
index = np.unravel_index(a.argmax(), a.shape)
print(index)
>>>(0, 1, 2)

一句话搞定,获得二维或多维数组最值的索引。

argmin()的用法

用来检索数组中最小值的位置,并返回其下标值。同理,argmax()函数就是用来检索最大值的下标,与argmin()函数用法相同。在argmin()函数的标准语法中,numpy.argmin(a, axis=None, out=None),其中的axis参数为默认和给定值时输出情况是不一样的。

在没有指定axis值的情况下,默认为None。在默认情况下,就相当于将n维的arry平铺在一起。举个简单的例子,当二维arry([1,2,3],[4,5,6])平铺开来就是([1,2,3,4,5,6])。

a =  np.array([[2,5,6],[7,6,1]])print(np.argmin(a))

对于这个二维arry来说,它的最小值是1,而1的下标为5,所以最后输出的值就是5。
当axis = 1时,按照方向来,对于[2,5,6]来说最小值的下标是0,对于[7,6,1]来说最小值的下标是2。所以,最后输出的值就是[0,2]。
当axis = 0时,这时按照方向来,[2,7],[5,6],[6,1]分别在一个轴上,所以检索每个轴上的最小值,并返回下标,最后就可以得到输出值[0,0,1]。

8.2.5 np.unique( )去除数组中的重复数字

该函数是去除数组中的重复数字,并进行排序之后输出。

8.2.6 reshape的坑——IndexError: invalid index to scalar variable.

生成了一个长度为10的一维数组,然后使用reshape转换成2x5的矩阵,但是在取矩阵值的时候出现索引错误

import numpy as np
a = np.arange(0,10)
a.reshape(2,5)
a[1][1]

原因:数组a经过reshape后,a中的内容没有变,需要重新赋值

import numpy as np
a = np.arange(0,10)
b = a.reshape(2,5)
b[1][1]
6

输出了正确值

8.2.7 np.where()——获取数组中指定元素的索引位置
import numpy as np
a = np.array([1,2,3,4,5,6,6,7,6])
b = np.where(a == 6)
# b = np.argwhere(a ==6 )
print(b)

9 音频处理

9.1 ffmpeg用法

9.1.1 剪切音视频
ffmpeg -i /data/video/1.mp4 -ss 00:00:05.000 -to 00:00:06.000 -strict -2 /data/video/splt.mp4

注:报错提示:The encoder ‘acc’ is experimental codecs are not enabled, add ‘-strict -2’ if you want to use it

9.1.2 从视频中提取音频

提取为mp3格式

ffmpeg -i huoying.mp4 -f mp3 -ar 16000 -ac 1 huoying.mp3
//huoying.mp4 视频文件
//-f mp3 mp3编码
//-ar 16000 音频采样率16000
//-ac 1 输出通道数1
//huoying.mp3输出的音频文件

提取为wav格式

ffmpeg -i huoying.mp4 -f wav -ar 16000 huoying.wav

9.2 librosa

9.2.1 librosa遇到的坑
  • Librosa:TypeError: expected string or buffer
    解决方法:见Librosa:TypeError: expected string or buffer

10 声学事件检测

10.1 检测指标(TP,FP,TN,FN,精确率召回率等直观图)


声学事件检测中的ER指标参照了语音识别中的ER计算方法。
ER的计算方法:(帧级别)
代码实现有两种方式:
法一:

def er_overall_framewise(O, T):  #O为参考标签,T为实际输出的标签if len(O.shape) == 3:O,T = utils.reshape_3Dto2D(O), utils.reshape_3Dto2D(T)FP = np.logical_and(T == 0, O == 1).sum(1)FN = np.logical_and(T == 1, O == 0).sum(1)S = np.minimum(FP, FN).sum()D = np.maximum(0, FN-FP).sum()I = np.maximum(0, FP-FN).sum()Nref = T.sum()ER = (S+D+I) / (Nref + 0.0)return ER

法二:与法一计算的方式不同,但结果一样

def er_overall_framewise(O, T):#这是错误的方法# if len(O.shape) == 3:#     O, T = utils.reshape_3Dto2D(O), utils.reshape_3Dto2D(T)# TP = ((2 * T - O) == 1).sum()# Nref, Nsys = T.sum(), O.sum()# ER = (max(Nref, Nsys) - TP) / (Nref + 0.0)#这是正确的方法if len(O.shape) == 3:O, T = utils.reshape_3Dto2D(O), utils.reshape_3Dto2D(T)TP = ((2 * T - O) == 1).sum(1)Nref, Nsys = T.sum(1), O.sum(1)a = np.vstack((Nref, Nsys))b = np.amax(a, axis = 0)Nref1 = T.sum()ER = (b - TP).sum() / (Nref1 + 0.0)return ER

python tensorflow2 deeplearning 音频处理 声学事件检测相关推荐

  1. 深度学习之视频入门经典+视频分类+视频行为识别+行为检测+视频事件识别+事件检测--附带源码和作者主页

    视频研究入门经典 Labor-Free Video Concept Learningby Jointly Exploiting Web Videos and Images intro: CVPR 20 ...

  2. 【AI达人特训营】法律领域篇章级多事件检测

    法律领域篇章级多事件检测 本项目针对法律案件中存在触发词不明显或者不包含触发词的事件,试图建立稳健的事件检测模型,用于判断法律案件中所包含的各个事件对应的事件类型,进而对后续的事件元素抽取任务提供支持 ...

  3. 网联V2X视频事件检测相机使用说明书

    1 产品概览 网联 V2X视频事件检测相机 视频事件检测相机 ,内置 1/1.8″逐行扫描 800万像素传感器:视 万像素传感器:视 频编码协议支持 H.265.H.264.MJPEG:具有 1个 1 ...

  4. Python,OpenCV轮廓属性、轮廓检测及绘制

    Python,OpenCV轮廓属性.轮廓检测及绘制 1. 效果图 2. 源码 2.1 轮廓属性 2.2 轮廓特征 参考 这篇博客将介绍OpenCV中的轮廓,轮廓的特征及属性(质心,面积,轮廓,近似轮廓 ...

  5. 使用Python,OpenCV,dlib进行睡意检测(疲劳驾驶检测)

    使用Python,OpenCV,dlib进行睡意检测,可以看做是对上一篇博客眨眼检测的进阶. 使用Python,OpenCV,dlib进行睡意检测 1. 睡意检测依赖及原理 依赖面部检测,面部标志检测 ...

  6. 细说浏览器特性检测(2)-通用事件检测

    在上一篇中介绍了jQuery1.4版本新增的几个浏览器特性检测方案和具体的目的,本文将以事件为中心,介绍一个较为完整.通用的事件检测方案. 事件检测,即检测某一事件在不同的浏览器中是否存在(可用),这 ...

  7. python代码示例下载-python爬取音频下载的示例代码

    抓取"xmly"鬼故事音频 import json # 在这个url,音频链接为JSON动态生成,所以用到了json模块 import requests headers = { & ...

  8. python 实现81个人脸关键点实时检测

    python 实现81个人脸关键点实时检测 文章目录: 一.81个关键点介绍 二.81 个关键点的使用 该库也是基于dlib实现的,还有face_recognition也同样是基于dlib来实现的 d ...

  9. Python定义点击右上角关闭按钮事件

    文章来自:https://www.cnblogs.com/iAmSoScArEd/p/11200029.html 爬虫.转载请注明出处. Python定义点击右上角关闭按钮事件 import tkin ...

最新文章

  1. NVIDIA安倍架构
  2. 树莓派:一个关于教育的故事
  3. abap-在table control中实现查找功能
  4. python 中numpy dot函数的使用方法
  5. xp下添加linux启动项,grub.cfg--XP+ Ubuntu10.04双系统安装后无XP启动项
  6. 【更新】PPT管理控件Aspose.Slides V17.5发布 | 附下载
  7. 433M数传电台窄带无线通讯技术手册
  8. 酷黑风个人主页+引导页源码
  9. tomcat日志中出现乱码
  10. app 常见网络性能
  11. idea创建springcloud项目_新手向,十分钟快速创建 Spring Cloud 项目
  12. JDK 14 性能提升,但 JDK 8 仍是最强王者!
  13. 《HTML5和JavaScript Web应用开发》——2.6 QA和设备测试
  14. Linux源码阅读(Web在线阅读)
  15. K8S你知道,K9S你可能也知道,那Lens呢?
  16. 下列c语言表达式正确,C语言试题-10(含答案
  17. .hex 文件详解 stm32
  18. SQL报错:Ambiguous column name ‘数据库某列’
  19. 使用字节流和字符流向浏览器输出数据
  20. 工作中使用到的单词(软件开发)_2021-12-26_备份

热门文章

  1. scrum立会报告+燃尽图(第三周第三次)
  2. 服务器通过笔记本电脑联网
  3. Allow Arbitrary Loads in Web Content与Allow Arbitrary Loads配置
  4. windows安装RabbitMQ以及Erlang
  5. WordPress 网站怎么做会员中心功能【会员中心】
  6. Twitter API
  7. PS制作各种证件照及换背景色
  8. 初级安全测试工程师的工资一般多少?
  9. 编程. 已知字符串:this is a test of java. 按要求执行以下操作: (1) 统计该字符串中字母s出现的次数 (2) 取出子字符串test (3) 用多种方式将本字
  10. 怎样把计算机里的W0rd放到电脑桌面,电脑怎么把Word图标放到桌面?把Word图标放到桌面的设置方法...