{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## PyTorch 实现自编码器 autoencoder\n", "\n", "理论部分参考:[自编码器变形和变分自编码器理论介绍及其 PyTorch 实现](https://dreamhomes.github.io/posts/202006021200.html)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1.5.0\n" ] } ], "source": [ "import os\n", "\n", "import numpy as np\n", "from sklearn import svm\n", "from sklearn.model_selection import GridSearchCV\n", "\n", "import torch\n", "import torch.nn as nn\n", "import torch.utils.data as Data\n", "import torchvision\n", "\n", "from matplotlib import cm\n", "import matplotlib.pyplot as plt\n", "from mpl_toolkits.mplot3d import Axes3D\n", "\n", "\n", "print(torch.__version__)" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# 超参数\n", "EPOCH = 8\n", "BATCH_SIZE = 64\n", "LR = 0.005" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Mnist数据" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "train_data = torchvision.datasets.MNIST(\n", " root='./data/mnist/',\n", " train=True, # this is training data\n", " transform=torchvision.transforms.ToTensor(), # Converts a PIL.Image or numpy.ndarray to torch.FloatTensor of shape (C x H x W) and normalize in the range [0.0, 1.0]\n", " download=True,\n", ")\n", "\n", "test_data = torchvision.datasets.MNIST(root='./data/mnist/', train=False)\n", "\n", "# 批训练 64 samples, 1 channel, 28x28 (64, 1, 28, 28)\n", "train_loader = Data.DataLoader(\n", " dataset=train_data,\n", " batch_size=BATCH_SIZE,\n", " shuffle=True,\n", " num_workers=0\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 构造模型" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "class AutoEncoder(nn.Module):\n", " def __init__(self):\n", " super(AutoEncoder, self).__init__()\n", "\n", " # encoder\n", " self.encoder = nn.Sequential(\n", " nn.Linear(28*28, 128),\n", " nn.Tanh(),\n", " nn.Linear(128, 64),\n", " nn.Tanh(),\n", " nn.Linear(64, 12),\n", " nn.Tanh(),\n", " nn.Linear(12, 3), # 进行 3D 图像可视化\n", " )\n", " # decoder\n", " self.decoder = nn.Sequential(\n", " nn.Linear(3, 12),\n", " nn.Tanh(),\n", " nn.Linear(12, 64),\n", " nn.Tanh(),\n", " nn.Linear(64, 128),\n", " nn.Tanh(),\n", " nn.Linear(128, 28*28),\n", " nn.Sigmoid(), # 激励函数让输出值在 (0, 1)\n", " )\n", "\n", " def forward(self, x):\n", " encoded = self.encoder(x)\n", " decoded = self.decoder(encoded)\n", " return encoded, decoded\n", "\n", " \n", "autoencoder = AutoEncoder()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 训练模型" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "optimizer = torch.optim.Adam(autoencoder.parameters(), lr=LR)\n", "loss_func = nn.MSELoss()\n", "\n", "for epoch in range(EPOCH):\n", " for step, (x, b_label) in enumerate(train_loader):\n", " b_x = x.view(-1, 28*28) # batch x, shape (batch, 28*28)\n", "\n", " encoded_x, decoded_x = autoencoder(b_x)\n", "\n", " loss = loss_func(decoded_x, b_x) \n", " optimizer.zero_grad() # clear gradients for this training step\n", " loss.backward() # backpropagation, compute gradients\n", " optimizer.step() " ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# 取200个数据来作图\n", "view_data = train_data.data[:200].view(-1, 28 * 28).type(torch.FloatTensor) / 255.\n", "encoded_data, _ = autoencoder(view_data) # 提取压缩的特征值\n", "fig = plt.figure(2)\n", "ax = Axes3D(fig) # 3D 图\n", "# x, y, z 的数据值\n", "X = encoded_data.data[:, 0].numpy()\n", "Y = encoded_data.data[:, 1].numpy()\n", "Z = encoded_data.data[:, 2].numpy()\n", "values = train_data.targets[:200].numpy() # 标签值\n", "for x, y, z, s in zip(X, Y, Z, values):\n", " c = cm.rainbow(int(255 * s / 9)) # 上色\n", " ax.text(x, y, z, s, backgroundcolor=c) # 标位子\n", "ax.set_xlim(X.min(), X.max())\n", "ax.set_ylim(Y.min(), Y.max())\n", "ax.set_zlim(Z.min(), Z.max())\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### SVM 对压缩后的特征进行数字识别" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(1000, 3)\n", "(1000,)\n", "test accuracy:\t 0.782\n" ] } ], "source": [ "# 取1000个训练数据来训练svm\n", "svm_train = train_data.data[:1000].view(-1, 28 * 28).type(torch.FloatTensor) / 255.\n", "s_t_x_afterencoder = autoencoder(svm_train)[0].data.numpy()\n", "print(s_t_x_afterencoder.shape)\n", "s_t_y = train_data.targets[:1000].numpy() # 标签值\n", "print(s_t_y.shape)\n", "# 取1000个训练数据来测试\n", "svm_test = test_data.data[:1000].view(-1, 28 * 28).type(torch.FloatTensor) / 255.\n", "s_te_x_afterencoder = autoencoder(svm_test)[0].data.numpy()\n", "s_te_y = test_data.targets[:1000].numpy() # label\n", "\n", "c_can = np.logspace(-3, 2, 10)\n", "gamma_can = np.logspace(-3, 2, 10)\n", "\n", "model = svm.SVC(kernel='rbf', decision_function_shape='ovr', random_state=1)\n", "clf = GridSearchCV(model, param_grid={'C': c_can, 'gamma': gamma_can}, cv=5, n_jobs=5)\n", "clf.fit(s_t_x_afterencoder, s_t_y)\n", "\n", "print('test accuracy:\\t', clf.score(s_te_x_afterencoder, s_te_y)) # 因为压缩到了三个特征,准确率并不是很高" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'cv': 5,\n", " 'error_score': nan,\n", " 'estimator__C': 1.0,\n", " 'estimator__break_ties': False,\n", " 'estimator__cache_size': 200,\n", " 'estimator__class_weight': None,\n", " 'estimator__coef0': 0.0,\n", " 'estimator__decision_function_shape': 'ovr',\n", " 'estimator__degree': 3,\n", " 'estimator__gamma': 'scale',\n", " 'estimator__kernel': 'rbf',\n", " 'estimator__max_iter': -1,\n", " 'estimator__probability': False,\n", " 'estimator__random_state': 1,\n", " 'estimator__shrinking': True,\n", " 'estimator__tol': 0.001,\n", " 'estimator__verbose': False,\n", " 'estimator': SVC(random_state=1),\n", " 'iid': 'deprecated',\n", " 'n_jobs': 5,\n", " 'param_grid': {'C': array([1.00000000e-03, 3.59381366e-03, 1.29154967e-02, 4.64158883e-02,\n", " 1.66810054e-01, 5.99484250e-01, 2.15443469e+00, 7.74263683e+00,\n", " 2.78255940e+01, 1.00000000e+02]),\n", " 'gamma': array([1.00000000e-03, 3.59381366e-03, 1.29154967e-02, 4.64158883e-02,\n", " 1.66810054e-01, 5.99484250e-01, 2.15443469e+00, 7.74263683e+00,\n", " 2.78255940e+01, 1.00000000e+02])},\n", " 'pre_dispatch': '2*n_jobs',\n", " 'refit': True,\n", " 'return_train_score': False,\n", " 'scoring': None,\n", " 'verbose': 0}" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "clf.get_params()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'C': 2.1544346900318843, 'gamma': 0.5994842503189409}" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "clf.best_params_" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.6" } }, "nbformat": 4, "nbformat_minor": 4 }