平时实践任务
Signed-off-by: less IS more <13190735+wnflt@user.noreply.gitee.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,663 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 读取图像数据"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import re\n",
|
||||
"import numpy as np\n",
|
||||
"import os\n",
|
||||
"import cv2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def getimgnames(path=None):\n",
|
||||
" \"\"\"\n",
|
||||
" 获取指定文件夹中的JPG图片名称(含路径)\n",
|
||||
" :param path: 指定文件夹\n",
|
||||
" :return: path中的所有JPG图片名称(含路径,例如:./path/image1.jpg)\n",
|
||||
" \"\"\"\n",
|
||||
" imgnames = []\n",
|
||||
" filenames = os.listdir(path) # 获取path中的所有文件名\n",
|
||||
" for i in filenames:\n",
|
||||
" if re.findall('^\\d+\\.jpg$', i) != []: # 在所有文件名中找出JPG图片名称\n",
|
||||
" imgnames.append(os.path.join(path, i)) # 将图片名称和路径合并、保存\n",
|
||||
" return imgnames"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 8,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class GetImgData:\n",
|
||||
"\n",
|
||||
" def __init__(self, dir='data//gray_face_images'):\n",
|
||||
" self.dir = dir\n",
|
||||
"\n",
|
||||
" def onehot(self, indexlist=None):\n",
|
||||
" b = np.zeros([len(indexlist), max(indexlist) + 1])\n",
|
||||
" b[np.arange(len(indexlist)), indexlist] = 1\n",
|
||||
" return b.tolist()\n",
|
||||
"\n",
|
||||
" def getfileandlabel(self):\n",
|
||||
" dicdir = {name: os.path.join(self.dir, name) for name in os.listdir(self.dir) if os.path.isdir(os.path.join(self.dir, name))}\n",
|
||||
" ## 生成字典,key为文件夹名称,value为文件夹路径\n",
|
||||
" # ditcir = {}\n",
|
||||
" # for name in os.listdir(self.dir):\n",
|
||||
" # if os.path.isdir(os.path.join(self.dir, name)):\n",
|
||||
" # dicdir[name] = os.path.join(self.dir, name)\n",
|
||||
" namelist, pathlist = dicdir.keys(), dicdir.values()\n",
|
||||
" indexlist = list(range(len(namelist)))\n",
|
||||
" return list(zip(pathlist, self.onehot(indexlist))), dict(zip(indexlist, namelist))\n",
|
||||
"\n",
|
||||
" def readimg(self):\n",
|
||||
" dir_label, num_name = self.getfileandlabel()\n",
|
||||
" imgs = []\n",
|
||||
" labels = []\n",
|
||||
" for path, label in dir_label:\n",
|
||||
" for imgname in getimgnames(path):\n",
|
||||
" img = cv2.imread(imgname)[:, :, 0:1]\n",
|
||||
" imgs.append(img)\n",
|
||||
" labels.append(label)\n",
|
||||
" data = np.array(imgs, dtype=np.float32) / 255\n",
|
||||
" y = np.array(labels, dtype=np.float32)\n",
|
||||
" return data, y, num_name"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 9,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"[[[[0.30588236]\n",
|
||||
" [0.32156864]\n",
|
||||
" [0.25490198]\n",
|
||||
" ...\n",
|
||||
" [0.2901961 ]\n",
|
||||
" [0.30980393]\n",
|
||||
" [0.30980393]]\n",
|
||||
"\n",
|
||||
" [[0.23529412]\n",
|
||||
" [0.23529412]\n",
|
||||
" [0.21568628]\n",
|
||||
" ...\n",
|
||||
" [0.24705882]\n",
|
||||
" [0.21960784]\n",
|
||||
" [0.30980393]]\n",
|
||||
"\n",
|
||||
" [[0.19215687]\n",
|
||||
" [0.17254902]\n",
|
||||
" [0.18431373]\n",
|
||||
" ...\n",
|
||||
" [0.27058825]\n",
|
||||
" [0.2509804 ]\n",
|
||||
" [0.28235295]]\n",
|
||||
"\n",
|
||||
" ...\n",
|
||||
"\n",
|
||||
" [[0.17254902]\n",
|
||||
" [0.16078432]\n",
|
||||
" [0.14509805]\n",
|
||||
" ...\n",
|
||||
" [0.18431373]\n",
|
||||
" [0.1764706 ]\n",
|
||||
" [0.18431373]]\n",
|
||||
"\n",
|
||||
" [[0.13725491]\n",
|
||||
" [0.15294118]\n",
|
||||
" [0.19215687]\n",
|
||||
" ...\n",
|
||||
" [0.16862746]\n",
|
||||
" [0.1764706 ]\n",
|
||||
" [0.19215687]]\n",
|
||||
"\n",
|
||||
" [[0.18039216]\n",
|
||||
" [0.14901961]\n",
|
||||
" [0.15294118]\n",
|
||||
" ...\n",
|
||||
" [0.13333334]\n",
|
||||
" [0.18039216]\n",
|
||||
" [0.15686275]]]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" [[[0.4117647 ]\n",
|
||||
" [0.36862746]\n",
|
||||
" [0.3647059 ]\n",
|
||||
" ...\n",
|
||||
" [0.30980393]\n",
|
||||
" [0.3372549 ]\n",
|
||||
" [0.3019608 ]]\n",
|
||||
"\n",
|
||||
" [[0.36078432]\n",
|
||||
" [0.3647059 ]\n",
|
||||
" [0.29803923]\n",
|
||||
" ...\n",
|
||||
" [0.30588236]\n",
|
||||
" [0.29411766]\n",
|
||||
" [0.31764707]]\n",
|
||||
"\n",
|
||||
" [[0.35686275]\n",
|
||||
" [0.27450982]\n",
|
||||
" [0.3019608 ]\n",
|
||||
" ...\n",
|
||||
" [0.3019608 ]\n",
|
||||
" [0.29803923]\n",
|
||||
" [0.28627452]]\n",
|
||||
"\n",
|
||||
" ...\n",
|
||||
"\n",
|
||||
" [[0.18431373]\n",
|
||||
" [0.15686275]\n",
|
||||
" [0.16078432]\n",
|
||||
" ...\n",
|
||||
" [0.19607843]\n",
|
||||
" [0.22352941]\n",
|
||||
" [0.2627451 ]]\n",
|
||||
"\n",
|
||||
" [[0.14117648]\n",
|
||||
" [0.15294118]\n",
|
||||
" [0.14509805]\n",
|
||||
" ...\n",
|
||||
" [0.23529412]\n",
|
||||
" [0.25882354]\n",
|
||||
" [0.28235295]]\n",
|
||||
"\n",
|
||||
" [[0.16078432]\n",
|
||||
" [0.13725491]\n",
|
||||
" [0.13725491]\n",
|
||||
" ...\n",
|
||||
" [0.16862746]\n",
|
||||
" [0.20784314]\n",
|
||||
" [0.22745098]]]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" [[[0.5372549 ]\n",
|
||||
" [0.5137255 ]\n",
|
||||
" [0.42352942]\n",
|
||||
" ...\n",
|
||||
" [0.2 ]\n",
|
||||
" [0.2 ]\n",
|
||||
" [0.20784314]]\n",
|
||||
"\n",
|
||||
" [[0.52156866]\n",
|
||||
" [0.45490196]\n",
|
||||
" [0.34117648]\n",
|
||||
" ...\n",
|
||||
" [0.18039216]\n",
|
||||
" [0.2 ]\n",
|
||||
" [0.23529412]]\n",
|
||||
"\n",
|
||||
" [[0.5137255 ]\n",
|
||||
" [0.38431373]\n",
|
||||
" [0.3254902 ]\n",
|
||||
" ...\n",
|
||||
" [0.1882353 ]\n",
|
||||
" [0.1764706 ]\n",
|
||||
" [0.1764706 ]]\n",
|
||||
"\n",
|
||||
" ...\n",
|
||||
"\n",
|
||||
" [[0.14117648]\n",
|
||||
" [0.21176471]\n",
|
||||
" [0.27058825]\n",
|
||||
" ...\n",
|
||||
" [0.07843138]\n",
|
||||
" [0.09803922]\n",
|
||||
" [0.07058824]]\n",
|
||||
"\n",
|
||||
" [[0.21960784]\n",
|
||||
" [0.2627451 ]\n",
|
||||
" [0.29803923]\n",
|
||||
" ...\n",
|
||||
" [0.07450981]\n",
|
||||
" [0.09411765]\n",
|
||||
" [0.09019608]]\n",
|
||||
"\n",
|
||||
" [[0.28235295]\n",
|
||||
" [0.2784314 ]\n",
|
||||
" [0.27450982]\n",
|
||||
" ...\n",
|
||||
" [0.08627451]\n",
|
||||
" [0.07450981]\n",
|
||||
" [0.08627451]]]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" ...\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" [[[0.18039216]\n",
|
||||
" [0.16470589]\n",
|
||||
" [0.16078432]\n",
|
||||
" ...\n",
|
||||
" [0.5568628 ]\n",
|
||||
" [0.54901963]\n",
|
||||
" [0.5529412 ]]\n",
|
||||
"\n",
|
||||
" [[0.18431373]\n",
|
||||
" [0.18431373]\n",
|
||||
" [0.19215687]\n",
|
||||
" ...\n",
|
||||
" [0.5411765 ]\n",
|
||||
" [0.54509807]\n",
|
||||
" [0.5529412 ]]\n",
|
||||
"\n",
|
||||
" [[0.2 ]\n",
|
||||
" [0.19215687]\n",
|
||||
" [0.19215687]\n",
|
||||
" ...\n",
|
||||
" [0.5411765 ]\n",
|
||||
" [0.54901963]\n",
|
||||
" [0.5568628 ]]\n",
|
||||
"\n",
|
||||
" ...\n",
|
||||
"\n",
|
||||
" [[0.6901961 ]\n",
|
||||
" [0.6862745 ]\n",
|
||||
" [0.61960787]\n",
|
||||
" ...\n",
|
||||
" [0.11764706]\n",
|
||||
" [0.11372549]\n",
|
||||
" [0.12941177]]\n",
|
||||
"\n",
|
||||
" [[0.61960787]\n",
|
||||
" [0.6784314 ]\n",
|
||||
" [0.5568628 ]\n",
|
||||
" ...\n",
|
||||
" [0.1254902 ]\n",
|
||||
" [0.1254902 ]\n",
|
||||
" [0.1254902 ]]\n",
|
||||
"\n",
|
||||
" [[0.54509807]\n",
|
||||
" [0.43137255]\n",
|
||||
" [0.4862745 ]\n",
|
||||
" ...\n",
|
||||
" [0.11764706]\n",
|
||||
" [0.10196079]\n",
|
||||
" [0.11764706]]]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" [[[0.34901962]\n",
|
||||
" [0.21568628]\n",
|
||||
" [0.19607843]\n",
|
||||
" ...\n",
|
||||
" [0.23921569]\n",
|
||||
" [0.21960784]\n",
|
||||
" [0.20784314]]\n",
|
||||
"\n",
|
||||
" [[0.24313726]\n",
|
||||
" [0.18431373]\n",
|
||||
" [0.19607843]\n",
|
||||
" ...\n",
|
||||
" [0.30588236]\n",
|
||||
" [0.22745098]\n",
|
||||
" [0.23137255]]\n",
|
||||
"\n",
|
||||
" [[0.22352941]\n",
|
||||
" [0.1764706 ]\n",
|
||||
" [0.19607843]\n",
|
||||
" ...\n",
|
||||
" [0.39215687]\n",
|
||||
" [0.25490198]\n",
|
||||
" [0.18431373]]\n",
|
||||
"\n",
|
||||
" ...\n",
|
||||
"\n",
|
||||
" [[0.7372549 ]\n",
|
||||
" [0.7294118 ]\n",
|
||||
" [0.70980394]\n",
|
||||
" ...\n",
|
||||
" [0.21568628]\n",
|
||||
" [0.20784314]\n",
|
||||
" [0.21960784]]\n",
|
||||
"\n",
|
||||
" [[0.7254902 ]\n",
|
||||
" [0.69411767]\n",
|
||||
" [0.69803923]\n",
|
||||
" ...\n",
|
||||
" [0.23529412]\n",
|
||||
" [0.16862746]\n",
|
||||
" [0.19607843]]\n",
|
||||
"\n",
|
||||
" [[0.68235296]\n",
|
||||
" [0.6784314 ]\n",
|
||||
" [0.6431373 ]\n",
|
||||
" ...\n",
|
||||
" [0.19215687]\n",
|
||||
" [0.16078432]\n",
|
||||
" [0.16470589]]]\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" [[[0.50980395]\n",
|
||||
" [0.3647059 ]\n",
|
||||
" [0.19607843]\n",
|
||||
" ...\n",
|
||||
" [0.41568628]\n",
|
||||
" [0.34901962]\n",
|
||||
" [0.24313726]]\n",
|
||||
"\n",
|
||||
" [[0.50980395]\n",
|
||||
" [0.29803923]\n",
|
||||
" [0.1764706 ]\n",
|
||||
" ...\n",
|
||||
" [0.44705883]\n",
|
||||
" [0.40784314]\n",
|
||||
" [0.31764707]]\n",
|
||||
"\n",
|
||||
" [[0.4509804 ]\n",
|
||||
" [0.25882354]\n",
|
||||
" [0.18039216]\n",
|
||||
" ...\n",
|
||||
" [0.48235294]\n",
|
||||
" [0.47058824]\n",
|
||||
" [0.3764706 ]]\n",
|
||||
"\n",
|
||||
" ...\n",
|
||||
"\n",
|
||||
" [[0.76862746]\n",
|
||||
" [0.7647059 ]\n",
|
||||
" [0.7490196 ]\n",
|
||||
" ...\n",
|
||||
" [0.12156863]\n",
|
||||
" [0.13333334]\n",
|
||||
" [0.14117648]]\n",
|
||||
"\n",
|
||||
" [[0.76862746]\n",
|
||||
" [0.7529412 ]\n",
|
||||
" [0.7254902 ]\n",
|
||||
" ...\n",
|
||||
" [0.11764706]\n",
|
||||
" [0.12941177]\n",
|
||||
" [0.1254902 ]]\n",
|
||||
"\n",
|
||||
" [[0.7529412 ]\n",
|
||||
" [0.7411765 ]\n",
|
||||
" [0.7176471 ]\n",
|
||||
" ...\n",
|
||||
" [0.11372549]\n",
|
||||
" [0.11372549]\n",
|
||||
" [0.1254902 ]]]]\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"if __name__ == '__main__':\n",
|
||||
" getimgdata = GetImgData()\n",
|
||||
" data, y, num_name = getimgdata.readimg()\n",
|
||||
" print(data)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import tensorflow as tf\n",
|
||||
"from getimgdata import GetImgData\n",
|
||||
"from random import sample\n",
|
||||
"from sklearn.model_selection import train_test_split\n",
|
||||
"import numpy as np"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"## 兼容v1\n",
|
||||
"tf.compat.v1.disable_eager_execution()\n",
|
||||
"\n",
|
||||
"getimgdata = GetImgData(dir='data//gray_face_images')\n",
|
||||
"data, y, num_name = getimgdata.readimg()\n",
|
||||
"X_tr, X_te, y_tr, y_te = train_test_split(data, y, test_size=0.2)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"# 构建CNN神经网络"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 12,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"class CnnNet:\n",
|
||||
"\n",
|
||||
" def __init__(self, imgs=None, labels=None, keep_prob_5=0.5, modeldir=None):\n",
|
||||
" tf.compat.v1.reset_default_graph() # 重置计算图\n",
|
||||
" self.imgs = imgs\n",
|
||||
" self.labels = labels\n",
|
||||
" self.modeldir = modeldir\n",
|
||||
" self.size = imgs.shape[1]\n",
|
||||
" self.keep_prob_5 = keep_prob_5\n",
|
||||
" self.outnode = labels.shape[1]\n",
|
||||
" self.x = tf.compat.v1.placeholder(tf.float32, [None, self.size, self.size, 1], name='x_data')\n",
|
||||
" self.y_ = tf.compat.v1.placeholder(tf.float32, [None, self.outnode])\n",
|
||||
"\n",
|
||||
" def weightVariable(self, shape): # 权值数组W\n",
|
||||
" init = tf.compat.v1.random_normal(shape, stddev=0.01)\n",
|
||||
" return tf.compat.v1.Variable(init)\n",
|
||||
"\n",
|
||||
" def biasVariable(self, shape): # 偏置项数组b\n",
|
||||
" init = tf.compat.v1.random_normal(shape)\n",
|
||||
" return tf.Variable(init)\n",
|
||||
"\n",
|
||||
" def conv2d(self, x, W): # 卷积\n",
|
||||
" return tf.nn.conv2d(x, W, strides=[1, 1, 1, 1], padding='SAME')\n",
|
||||
"\n",
|
||||
" def maxPool(self, x): # max池化\n",
|
||||
" return tf.nn.max_pool(x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')\n",
|
||||
"\n",
|
||||
" def dropout(self, x, keep): # 随机让某些权重不更新,保持某个数\n",
|
||||
" return tf.nn.dropout(x, keep)\n",
|
||||
"\n",
|
||||
" def cnnLayer(self):\n",
|
||||
" \"\"\"\n",
|
||||
" cnn神经网络结构\n",
|
||||
" :return:\n",
|
||||
" \"\"\"\n",
|
||||
" # ===第一次卷积&池化====\n",
|
||||
" W1 = self.weightVariable(shape=[3, 3, 1, 32])\n",
|
||||
" b1 = self.biasVariable([32])\n",
|
||||
" conv1 = tf.nn.relu(self.conv2d(self.x, W1) + b1)\n",
|
||||
" pool1 = self.maxPool(conv1)\n",
|
||||
" drop1 = self.dropout(pool1, self.keep_prob_5)\n",
|
||||
"\n",
|
||||
" # ===第二次卷积&池化====\n",
|
||||
" W2 = self.weightVariable([3, 3, 32, 64])\n",
|
||||
" b2 = self.biasVariable([64])\n",
|
||||
" conv2 = tf.nn.relu(self.conv2d(drop1, W2) + b2)\n",
|
||||
" pool2 = self.maxPool(conv2)\n",
|
||||
" drop2 = self.dropout(pool2, self.keep_prob_5)\n",
|
||||
"\n",
|
||||
" # ===第三次卷积&池化====\n",
|
||||
" W3 = self.weightVariable([3, 3, 64, 64])\n",
|
||||
" b3 = self.biasVariable([64])\n",
|
||||
" conv3 = tf.nn.relu(self.conv2d(drop2, W3) + b3)\n",
|
||||
" pool3 = self.maxPool(conv3)\n",
|
||||
" drop3 = self.dropout(pool3, self.keep_prob_5)\n",
|
||||
"\n",
|
||||
" # ===全连接层1====\n",
|
||||
" Wf = self.weightVariable([8*8*64, 512])\n",
|
||||
" bf = self.biasVariable([512])\n",
|
||||
" drop3_flat = tf.reshape(drop3, [-1, 8*8*64])\n",
|
||||
" dense = tf.nn.relu(tf.matmul(drop3_flat, Wf) + bf)\n",
|
||||
" dropf = self.dropout(dense, 0.75)\n",
|
||||
"\n",
|
||||
" # ===输出层====\n",
|
||||
" W_out = self.weightVariable([512, self.outnode])\n",
|
||||
" b_out = self.biasVariable([self.outnode])\n",
|
||||
" out = tf.add(tf.matmul(dropf, W_out), b_out, name='out')\n",
|
||||
" return out\n",
|
||||
" \n",
|
||||
" def cnnTrain(self, maxiter=1000, accu=0.99, batch_size=100):\n",
|
||||
" \"\"\"\n",
|
||||
" 依据训练样本的模型输出与样本实际值进行模型训练\n",
|
||||
" :param maxiter: 最大迭代次数\n",
|
||||
" :param accu: 精度阈值,当训练精度大于accu时则停止训练\n",
|
||||
" :param batch_size: 每轮训练的样本数\n",
|
||||
" :return: 无返回,但是当模型精度满足要求后会将模型保存\n",
|
||||
" \"\"\"\n",
|
||||
" out = self.cnnLayer()\n",
|
||||
" cross_entropy = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=self.y_, logits=out))\n",
|
||||
" train_step = tf.compat.v1.train.AdamOptimizer(0.01).minimize(cross_entropy)\n",
|
||||
" acc = tf.reduce_mean(tf.cast(tf.equal(tf.argmax(out, 1), tf.argmax(self.y_, 1)), tf.float32))\n",
|
||||
"\n",
|
||||
" saver = tf.compat.v1.train.Saver()\n",
|
||||
" sess = tf.compat.v1.Session()\n",
|
||||
" sess.run(tf.compat.v1.global_variables_initializer()) # 执行变量初始化操作\n",
|
||||
" for n in range(maxiter):\n",
|
||||
" ind = sample(range(len(self.imgs)), batch_size)\n",
|
||||
" batch_x = self.imgs[ind]\n",
|
||||
" batch_y = self.labels[ind]\n",
|
||||
" sess.run(train_step, feed_dict={self.x: batch_x, self.y_: batch_y})\n",
|
||||
" if n%100 == 0:\n",
|
||||
" acc_tr = sess.run(acc, feed_dict={self.x: batch_x, self.y_: batch_y})\n",
|
||||
" print('轮数:', n, ' the train accuracy is :', acc_tr)\n",
|
||||
" if (acc_tr > accu) and (n >= 499):\n",
|
||||
" saver.save(sess, self.modeldir)\n",
|
||||
" break\n",
|
||||
" elif n == (maxiter-1):\n",
|
||||
" saver.save(sess, self.modeldir)\n",
|
||||
" sess.close()\n",
|
||||
"\n",
|
||||
" def predict(self, test_x=None):\n",
|
||||
" \"\"\"\n",
|
||||
" 预测函数,导入已训练好的模型后再将新样本数据放入,进行模型预测\n",
|
||||
" :param test_x: 测试样本的自变量\n",
|
||||
" :return: 模型对测试样本的预测结果\n",
|
||||
" 1: 预测结果(数字标签:0,1,2,3,4,5,...)\n",
|
||||
" pre: 样本属于各类别的概率,形如:[[0.1, 0.1, 0.0, 0.0, 0.0, 0.8]]\n",
|
||||
" \"\"\"\n",
|
||||
" out = self.cnnLayer()\n",
|
||||
" with tf.compat.v1.Session() as sess:\n",
|
||||
" saver = tf.compat.v1.train.Saver()\n",
|
||||
" saver.restore(sess, self.modeldir)\n",
|
||||
" graph = tf.get_default_graph()\n",
|
||||
" x = graph.get_tensor_by_name('x_data:0')\n",
|
||||
" pre = sess.run(out, feed_dict={x: test_x})\n",
|
||||
" acc_te = sum(np.argmax(pre, 1) == np.argmax(y_te, 1)) / len(pre)\n",
|
||||
" return np.argmax(pre, 1), acc_te"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 模型训练"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 11,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"轮数: 0 the train accuracy is : 0.19\n",
|
||||
"轮数: 100 the train accuracy is : 0.88\n",
|
||||
"轮数: 200 the train accuracy is : 0.97\n",
|
||||
"轮数: 300 the train accuracy is : 0.97\n",
|
||||
"轮数: 400 the train accuracy is : 0.99\n",
|
||||
"轮数: 500 the train accuracy is : 0.94\n",
|
||||
"轮数: 600 the train accuracy is : 0.96\n",
|
||||
"轮数: 700 the train accuracy is : 0.97\n",
|
||||
"轮数: 800 the train accuracy is : 0.96\n",
|
||||
"轮数: 900 the train accuracy is : 1.0\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"cnn_net = CnnNet(imgs=X_tr, labels=y_tr, modeldir='temp/train_model')\n",
|
||||
"cross = cnn_net.cnnTrain()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## 模型预测"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 13,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"WARNING:tensorflow:From D:\\TEMP\\ipykernel_17504\\2843680607.py:26: The name tf.nn.max_pool is deprecated. Please use tf.nn.max_pool2d instead.\n",
|
||||
"\n",
|
||||
"WARNING:tensorflow:From D:\\TEMP\\ipykernel_17504\\2843680607.py:29: calling dropout (from tensorflow.python.ops.nn_ops) with keep_prob is deprecated and will be removed in a future version.\n",
|
||||
"Instructions for updating:\n",
|
||||
"Please use `rate` instead of `keep_prob`. Rate should be set to `rate = 1 - keep_prob`.\n",
|
||||
"INFO:tensorflow:Restoring parameters from temp/train_model\n",
|
||||
"WARNING:tensorflow:From D:\\TEMP\\ipykernel_17504\\2843680607.py:113: The name tf.get_default_graph is deprecated. Please use tf.compat.v1.get_default_graph instead.\n",
|
||||
"\n",
|
||||
"the test accuracy is : 0.9845201238390093\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"cnn_net = CnnNet(imgs=X_tr, labels=y_tr, modeldir='temp/train_model')\n",
|
||||
"pre, acc_te = cnn_net.predict(test_x=X_te)\n",
|
||||
"print('the test accuracy is :', acc_te)"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.7.9 ('venv': venv)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.7.9"
|
||||
},
|
||||
"vscode": {
|
||||
"interpreter": {
|
||||
"hash": "a82d1522e399fc49d60c7b85358aba15d27930532737449decaece807d60f8db"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,307 @@
|
||||
import os
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import torch
|
||||
import torch.nn as nn
|
||||
import torch.optim as optim
|
||||
from torch.utils.data import Dataset, DataLoader
|
||||
|
||||
# 配置训练环境和超参数
|
||||
# 根据系统的可用设备选择将张量放到GPU1或CPU上进行运算
|
||||
device = torch.device('cuda:1' if torch.cuda.is_available() else 'cpu')
|
||||
|
||||
# 配置其他超参数
|
||||
batch_size = 256 # 每个批次训练的样本数
|
||||
num_workers = 0
|
||||
learning_rate = 1e-4
|
||||
epochs = 20 # 迭代次数
|
||||
|
||||
# 数据的读入和加载
|
||||
from torchvision import transforms
|
||||
|
||||
image_size = 28
|
||||
data_transform = transforms.Compose([
|
||||
transforms.ToPILImage(), # 将张量转化为PIL图像对象
|
||||
transforms.Resize(image_size),
|
||||
transforms.ToTensor() # 将PIL图像转化为张量
|
||||
])
|
||||
|
||||
# 读入csv格式的数据,自行构建Dataset类
|
||||
class FMDataset(Dataset):
|
||||
def __init__(self, df, transform=None): # 默认没有数据转换操作
|
||||
self.df = df
|
||||
self.transform = transform
|
||||
self.images = df.iloc[:, 1:].values.astype(np.uint8) # .values将提取到的DataFrame数据转化为(无符号八位整数)numpy数组
|
||||
self.labels = df.iloc[:, 0].values
|
||||
|
||||
def __len__(self): # 魔术方法,用于定义类的行为和操作,以模拟内置类型或实现类的特定功能
|
||||
return len(self.images) # 这里用于返回图片数据集的长度
|
||||
|
||||
def __getitem__(self, idx): # 用于通过索引来访问数据集和标签
|
||||
image = self.images[idx].reshape(28, 28, 1)
|
||||
label = int(self.labels[idx]) # 根据索引获取对应对象
|
||||
if self.transform is not None:
|
||||
image = self.transform(image)
|
||||
else:
|
||||
image = torch.tensor(image/255., dtype=torch.float) # 归一化
|
||||
label = torch.tensor(label, dtype=torch.long)
|
||||
return image, label # 返回图像和标签元组
|
||||
|
||||
|
||||
train_df = pd.read_csv('fashion-mnist_train.csv')
|
||||
test_df = pd.read_csv('fashion-mnist_test.csv')
|
||||
train_data = FMDataset(train_df, data_transform)
|
||||
test_data = FMDataset(test_df, data_transform)
|
||||
|
||||
# 定义DataLoader类,以便在训练和测试时加载数据。
|
||||
# DataLoader类是pytorch自带的类,将数据集封装为可迭代的数据加载器
|
||||
train_loader = DataLoader(train_data, batch_size=batch_size,
|
||||
shuffle=True, num_workers=num_workers, # shuffle=True:在每个epoch开始时对数据集进行随机重排
|
||||
drop_last=True) # 如果最后一个批次样本数不足将被丢弃
|
||||
test_loader = DataLoader(test_data, batch_size=batch_size,
|
||||
shuffle=False, num_workers=num_workers)
|
||||
|
||||
# 可视化操作,用于验证读入的数据是否正确
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
image, label = next(iter(train_loader)) # iter()将train_loader转化为一个迭代器对象,next()用于获得下一个批次的数据
|
||||
print(image.shape, label.shape)
|
||||
plt.imshow(image[0][0], cmap='gray') # matplotlib中用于显示图像的函数
|
||||
plt.show()
|
||||
|
||||
|
||||
# 手搭CNN网络
|
||||
class Net(nn.Module):
|
||||
def __init__(self):
|
||||
super(Net, self).__init__()
|
||||
self.conv = nn.Sequential(
|
||||
nn.Conv2d(1, 32, 5),
|
||||
nn.ReLU(),
|
||||
nn.MaxPool2d(2, stride=2),
|
||||
nn.Dropout(0.3),
|
||||
nn.Conv2d(32, 64, 5),
|
||||
nn.ReLU(),
|
||||
nn.MaxPool2d(2, stride=2),
|
||||
nn.Dropout(0.3)
|
||||
)
|
||||
self.fc = nn.Sequential(
|
||||
nn.Linear(64 * 4 * 4, 512),
|
||||
nn.ReLU(),
|
||||
nn.Linear(512, 10)
|
||||
)
|
||||
|
||||
def forward(self, x):
|
||||
x = self.conv(x)
|
||||
x = x.view(-1, 64 * 4 * 4)
|
||||
x = self.fc(x)
|
||||
return x
|
||||
|
||||
|
||||
model = Net()
|
||||
model = model.cpu()
|
||||
|
||||
# 设定损失函数
|
||||
# torch.nn模块自带交叉熵损失
|
||||
criterion = nn.CrossEntropyLoss()
|
||||
|
||||
# 设定优化器
|
||||
optimizer = optim.Adam(model.parameters(), lr=0.001)
|
||||
|
||||
# 训练和测试
|
||||
def train(epoch):
|
||||
model.train()
|
||||
train_loss = 0
|
||||
for data, label in train_loader:
|
||||
data, label = data.cpu(), label.cpu()
|
||||
optimizer.zero_grad()
|
||||
output = model(data)
|
||||
loss = criterion(output, label)
|
||||
loss.backward()
|
||||
optimizer.step()
|
||||
train_loss += loss.item() * data.size(0)
|
||||
train_loss = train_loss / len(train_loader.dataset)
|
||||
print('Epoch: {}\tTraining Loss: {:.4f}'.format(epoch, train_loss))
|
||||
|
||||
def val(epoch):
|
||||
model.eval()
|
||||
val_loss = 0
|
||||
gt_labels = []
|
||||
pred_labels = []
|
||||
with torch.no_grad():
|
||||
for data, label in test_loader:
|
||||
data, label = data.cpu(), label.cpu()
|
||||
output = model(data)
|
||||
preds = torch.argmax(output, 1)
|
||||
gt_labels.append(preds.cpu().data.numpy())
|
||||
pred_labels.append(preds.cpu().data.numpy())
|
||||
loss = criterion(output, label)
|
||||
val_loss += loss.item() * data.size(0)
|
||||
val_loss = val_loss / len(test_loader.dataset)
|
||||
gt_labels, pred_labels = np.concatenate(gt_labels), np.concatenate(pred_labels)
|
||||
acc = np.sum(gt_labels == pred_labels) / len(pred_labels)
|
||||
print('Epoch: {} \tValidation Loss: {:.4f}, Accuracy:{:.4f}'.format(epoch, val_loss, acc))
|
||||
|
||||
|
||||
for epoch in range(1, epochs + 1):
|
||||
train(epoch)
|
||||
val(epoch)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user