另外,其实1 x 1的卷积不过是实现多通道之间的线性叠加,如果你还记得上面多通道的意思,1 x 1 卷积改变卷积核的数量,无非就是使得不同的feature map进行线性叠加而已(feature map指的是最后输出的每一层叠加出来的),因为通道的数量可以随时改变,1 x 1卷积也可以有跨通道信息交流的内涵。
train_ = []test_acc = []for epoch in range(1,EPOCHS+1): train_loss = train(model,DEVICE,train_loader,optimizer,epoch) acc = test(model,DEVICE,test_loader) train_.append(train_loss) test_acc.append(acc) visualize(train_,[i for i in range(20)],"loss")visualize(test_acc,[i for i in range(20)],"accuracy")
接下来使用tensorflow-gpu 1.14.0再实操一下
from tensorflow import kerasimport numpy as npimport matplotlib.pyplot as plt
import tensorflow as tfimport matplotlib as mplimport sys # solve could not create cudnn handle: CUDNN_STATUS_INTERNAL_ERRORconfig = tf.compat.v1.ConfigProto()config.gpu_options.allow_growth = Truesession = tf.compat.v1.InteractiveSession(config=config) # 不同库版本,使用此代码块查看print(sys.version_info)for module in mpl,np,tf,keras: print(module.__name__,module.__version__) '''sys.version_info(major=3, minor=6, micro=9, releaselevel='final', serial=0)matplotlib 3.3.4numpy 1.16.0tensorflow 1.14.0tensorflow.python.keras.api._v1.keras 2.2.4-tf'''# If you get numpy futurewarning,then try numpy 1.16.0 # load train and test(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data() # Scale images to the [0, 1] rangex_train = x_train.astype("float32") / 255x_test = x_test.astype("float32") / 255 # 1 Byte = 8 Bits,2^8 -1 = 255。[0,255]代表图上的像素,同时除以一个常数进行归一化。1 就代表全部涂黑。0 就代表没涂 # Make sure images have shape (28, 28, 1)x_train = np.expand_dims(x_train, -1)x_test = np.expand_dims(x_test, -1) # CNN 的输入方式必须得带上channel,这里扩充一下维度 # convert class vectors to binary class matricesy_train = keras.utils.to_categorical(y_train, 10)y_test = keras.utils.to_categorical(y_test, 10) # y 属于 [0,9]代表手写数字的标签,这里将它转换为0-1表示,可以类比one-hot,举个例子,如果是2 # [[0,0,1,0,0,0,0,0,0,0]……] model = keras.Sequential( [ keras.Input(shape=(28, 28, 1)), keras.layers.Conv2D(filters=32, kernel_size=(3, 3), activation="relu"), keras.layers.MaxPooling2D(pool_size=(2, 2)), keras.layers.Conv2D(filters=64, kernel_size=(3, 3), activation="relu"), keras.layers.MaxPooling2D(pool_size=(2, 2)), keras.layers.Flatten(), keras.layers.Dense(units=10, activation="softmax"), ]) # 注意,Conv2D里面有激活函数不代表在卷积和池化的时候进行。而是在DNN里进行,最后拉直后直接接softmax就行 # kernel_size 代表滤波器的大小,pool_size 代表池化的滤波器的大小 model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"]) model.summary() history = model.fit(x_train, y_train, batch_size=128, epochs=15, validation_split=0.1) #10层交叉检验score = model.evaluate(x_test, y_test)print("Test loss:", score[0])print("Test accuracy:", score[1]) # Test loss: 0.03664601594209671# Test accuracy: 0.989300012588501 # visualize accuracy and lossdef plot_(history,label): plt.plot(history.history[label]) plt.plot(history.history["val_" + label]) plt.title("model " + label) plt.ylabel(label) plt.xlabel("epoch") plt.legend(["train","test"],loc = "upper left") plt.show() plot_(history,"acc")plot_(history,"loss")