keras 基础小记

model.add

model = Sequential()
model.add(Dense(output_dim=1, input_dim=1))

每次model.add就是添加一层,不用写入权重这些参数。
W, b = model.layers[0].get_weights()是第一层的参数。

特征标准化

不同特征所占比重不同,把特征们的所占比重都设置为差不多,都在(0,1)之间

keras classifier分类 教程

https://morvanzhou.github.io/tutorials/machine-learning/keras/2-2-classifier/

下载mnist数据集

from keras.datasets import mnist  #就开始下载了

(x_train, y_train), (x_test, y_test) = mnist.load_data()

把标签y变成one-hot形式

mnist数据集的y是对应的某一个数字(0-9),要把它变成1*10的向量,1的话是0100000000的形式,属于哪个数字,就在哪个位置为 1,其他位置都是 0的形式,叫做one hot独热。

要用到 Keras 改造的 numpy 的一个函数 np_utils.to_categorical

from keras.utils import np_utils

y_train = np_utils.to_categorical(y_train, num_classes=10)

建立神经网络

1.Sequential,称为序贯模型,也就是单输入单输出,一条路通到底,层与层之间只有相邻关系,跨层连接统统没有
from keras.layers import Dense, Activation
from keras.models import Sequential

model = Sequential([
    Dense(32, input_dim=784),
    Activation('relu'),
    Dense(10),
    Activation('softmax'),
])

或者写成:

model = Sequential
model.add(Dense(32, input_dim=784))
model.add(Activation('relu'))
model.add(Dense(10))
model.add(Activation('softmax'))

第一层Dense(输出维度,输入维度),之后Dense就不用写输入维度了,只需要写输出维度,默认输入维度就是上一层的输出。

model.add 一层一层添加神经层

Dense是2D层,支持通过指定其输入维度input_dim来隐含的指定输入数据shape,是一个Int类型的数据
model.add(Dense(32, input_dim=784)) == model.add(Dense(32, input_shape=(784,)))

2.Graph,即图模型,这个模型支持多输入多输出,层与层之间想怎么连怎么连,但是编译速度慢。在Keras1和Keras2中,图模型被移除,而增加了了“functional model API”,

激活模型

model.compile 激励神经网络。

优化器,可以是默认的,也可以是我们在上一步rmsprop = RMSprop(lr=0.001, rho=0.9, epsilon=1e-08, decay=0.0)定义的。 损失函数,分类和回归问题的不一样,用的是交叉熵。 metrics,里面可以放入需要计算的 cost,accuracy,score 等。

# We add metrics to get more results you want to see
model.compile(optimizer=rmsprop,
              loss='categorical_crossentropy',
              metrics=['accuracy'])

这里若optimizer='rmsproc'加了引号,说明用的是默认的rmsproc优化器,而不是我们上面定义的。

训练网络

法一. model.fit函数。

这里用到的是 fit 函数,把训练集的 x 和 y 传入之后,nb_epoch 表示把整个数据训练多少次,batch_size 每批处理32个。

model.fit(X_train, y_train, epoch=2, batch_size=32)

法二. model.train_on_batch
model.train_on_batch 一批一批的训练 X_train, Y_train。默认的返回值是 cost

for step in range(301):
cost = model.train_on_batch(X_train, Y_train)
if step % 100 == 0:
    print('train cost: ', cost)
    
   
result = model.fit(x_train, y_train,
          batch_size=batch_size,
          epochs=epochs,
          verbose=1,
          validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

测试模型

用到的函数是 model.evaluate,输入测试集的x和y, 输出 costweightsbiases
这里 weights 和 biases 取的是模型的第一层 model.layers[0] 学习到的参数。

loss, accuracy = model.evaluate(X_test, y_test)
或者cost = model.evaluate(X_test, Y_test, batch_size=40)
print('test loss: ', loss)
print('test accuracy: ', accuracy)
W, b = model.layers[0].get_weights()
print('Weights=', W, '\nbiases=', b)

基础知识

batch

深度学习的优化算法,说白了就是梯度下降。每次的参数更新有两种方式。

  1. BGD : 遍历全部数据集算一次损失函数,然后算函数对各个参数的梯度,更新梯度。这种方法每更新一次参数都要把数据集里的所有样本都看一遍,计算量开销大,计算速度慢,不支持在线学习,这称为Batch gradient descent,批梯度下降。

  2. SGD : 另一种,每看一个数据就算一下损失函数,然后求梯度更新参数,这个称为随机梯度下降,stochastic gradient descent。这个方法速度比较快,但是收敛性能不太好,可能在最优点附近晃来晃去,hit不到最优点。两次参数的更新也有可能互相抵消掉,造成目标函数震荡的比较剧烈。

  3. mini-batch : 为了克服两种方法的缺点,现在一般采用的是一种折中手段,mini-batch gradient decent,小批的梯度下降,这种方法把数据分为若干个批,按批来更新参数,这样,一个批中的一组数据共同决定了本次梯度的方向,下降起来就不容易跑偏,减少了随机性。另一方面因为批的样本数与整个数据集相比小了很多,计算量也不是很大。

基本上现在的梯度下降都是基于mini-batch的,所以Keras的模块中经常会出现batch_size,就是指这个。

顺便说一句,Keras中用的优化器SGD是stochastic gradient descent的缩写,但不代表是一个样本就更新一回,还是基于mini-batch的。

epochs

epochs指的就是训练过程中数据将被“轮”多少次.

验证集

验证集的作用是当通过训练集训练出多个模型后,为了能找出效果最佳的模型,使用各个模型对验证集数据进行预测,并记录模型准确率。选出效果最佳的模型所对应的参数,即用来调整模型参数。如svm中的参数c和核函数等。

因为参数是超参数。

keras CNN

参考 https://morvanzhou.github.io/tutorials/machine-learning/keras/2-3-CNN/

数据处理

X_train = X_train.reshape(-1, 1,28, 28)/255.        #(sample, channels(RGB), height, width)

这里-1代表sample个数, 以后不想特地去知道具体数字,就直接用-1表示即可。

卷积层

model.add(Convolution2D(
    batch_input_shape=(None, 1, 28, 28),
    filters=32,
    kernel_size=5,
    strides=1,
    padding='same',     # Padding method
    data_format='channels_first',
))

filters=32:32个滤波器;

Padding方法是same即不改变数据的长度和宽度

data_format: tensorflow是data_format=‘channels_last’,格式是(-1,28,28,3);而channels_first是(-1,3,28,28)这种形式

全连接层

需要将数据抹平成一维,再添加全连接层FC:

model.add(Flatten())

数据集datesets路径

自带的脚本里的地址,下载数据集太慢。可以本地下好,拷贝到~/.keras/datasets/路径下(隐藏文件夹)

其中:cifar10需要改文件名为cifar-10-batches-py.tar.gz ,cifar100改为 cifar-100-python.tar.gz , mnist改为 mnist.npz

预训练models放到 ~/.keras/models/ 路径下面即可。

显示图片

from keras.datasets import mnist
import matplotlib.pyplot as plt
(X_train, y_train), (X_test, y_test) = mnist.load_data()

#y_train:0-9的数字 one-hot之前
#来自knn.ipynb
classes = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
num_classes = len(classes)
samples_per_class = 7
for y, cls in enumerate(classes):
    idxs = np.flatnonzero(y_train == y)     # 返回y_train==y时,对应的y_train的下标
    idxs = np.random.choice(idxs, samples_per_class, replace=False) #从这些满足条件y_train==y的样本中 随机选出samples_per_class个
    for i, idx in enumerate(idxs):
        plt_idx = i * num_classes + y + 1
        plt.subplot(samples_per_class, num_classes, plt_idx) #窗口被分为samples_per_class行,num_classes列
        plt.imshow(X_train[idx].astype('uint8'))
        plt.axis('off')
        if i == 0:
            plt.title(cls)
plt.show()

(1000, )写法

变量写成(1000, ),打开看是一列,但其实仍是一行[7,2,1…4,5],不要被骗了。

错误集

ValueError: Error when checking target: expected activation_48 to have 2 dimensions, but got array with shape (50000, 1, 10)

这是因为cifar10y_trainy_test传进来是(10000,1)就是[[1],[2]]这种表达式,而不是一行,所以要改成(10000,)这种表达式。方法(用reshape):y_test = y_test.reshape(y_test.shape[0], )

画loss和accuracy的图

plt.figure
plt.plot(result.epoch,result.history['acc'],label="acc")
plt.plot(result.epoch,result.history['val_acc'],label="val_acc")
plt.scatter(result.epoch,result.history['acc'],marker='*')
plt.scatter(result.epoch,result.history['val_acc'])
plt.legend(loc='under right')
plt.show()

plt.figure
plt.plot(result.epoch,result.history['loss'],label="loss")
plt.plot(result.epoch,result.history['val_loss'],label="val_loss")
plt.scatter(result.epoch,result.history['loss'],marker='*')
plt.scatter(result.epoch,result.history['val_loss'],marker='*')
plt.legend(loc='upper right')
plt.show()

result是前面result = model.fit()

打印中间层输出

法1.新建model,model的输入input为想要输入的层,输出output为想要输出的层,此mdoel非之前的model,新Model(新名称)

from keras.models import Model
intermediate_layer_model = Model(inputs=model.input,outputs=model.get_layer('a1').output)   # 新名称,中间层
# 这里的get_layer('a1')是上面model.add时命名的,比如model.add(Activation('relu',name='a1'))
# model.add(Dense(num_classes,activation='softmax',name='dense_2'))等等
intermediate_layer = dense1_layer_model.predict(x_train)

print (intermediate_layer.shape)
print (intermediate_layer[0])
plt.imshow(intermediate_layer[0][:][:][0])  #根据变量shape来改
plt.show()

回掉函数callbacks

1.tensorboard
从输入开始

with tf.name_scope('inputs'):
    xs = tf.placeholder(tf.float32, [None, 1], name='x_input')#这个名字会显示在tensorboard上
    ys = tf.placeholder(tf.float32, [None, 1], name='y_input')

赋给变量/占位符一个name,然后前头的地方用with tf.name_scope('自己取一个'),下面要包含在里头的变量,做缩进。
activation不用写,因为默认会写。

with tf.name_scope(layer_name):
        with tf.name_scope('weights'):
            Weights = tf.Variable(tf.random_normal([in_size, out_size]), name='W')
            tf.summary.histogram(layer_name + '/weights', Weights)  #保存成histogram的观察方式 概率分布 颜色深出现的多

write:在定义好session(sess = tf.Session())后写的。

merged = tf.summary.merge_all() #用merge
writer = tf.train.SummaryWriter('logs/', sess.graph)`把整个框架保存,之后才能load到浏览器里
init = tf.global_variables_initializer()
sess.run(init)
for i in range(1000):
    sess.run(train_step, feed_dict={xs: x_data, ys: y_data})
    if i % 50 == 0:
        result = sess.run(merged,
                          feed_dict={xs: x_data, ys: y_data})
        writer.add_summary(result, i)

在终端的log路径下(前一路径),先sudo chmod -R 777 logs,再运行tensorboard --logdir='logs/',得到一个网址http://xielongdeMacBook-Pro.local:6006,输入chrome浏览器地址栏中,发现无法显示,再在地址栏中输入localhost:6006(http://localhost:6006/#graphs),就可以了。

tf.summary.histogram(layer_name + '/outputs', outputs) #这个在tensorboard网页中对应 histogram 的记录方式
tf.summary.scalar('loss', loss) #这个在tensorboard网页中对应 event 的记录方式

报错

/Users/yelong/anaconda3/lib/python3.6/site-packages/h5py/init.py:36: FutureWarning: Conversion of the second argument of issubdtype from float to np.floating is deprecated. In future, it will be treated as np.float64 == np.dtype(float).type.
from ._conv import register_converters as _register_converters

解决方法:https://stackoverflow.com/questions/48340392/futurewarning-conversion-of-the-second-argument-of-issubdtype-from-float-to
在代码开头填上:

import os
os.environ["TF_CPP_MIN_LOG_LEVEL"]="3"

pip安装

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple keras==2.1.6

你可能感兴趣的:(深度学习)