diff --git a/README.md b/README.md index 8a31fd7..6997d6f 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ pip install -r requirements.txt ## linux ```shell -conda create -n ail-tf python=3.9 -y +conda create -n ail-tf python=3.10 -y conda create -n ail-pt python=3.10 -y conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia @@ -30,6 +30,19 @@ pip install tensorflow pip install -r requirements.txt ``` +## windows +```shell +conda create -n ail-tf python=3.9 -y +conda create -n ail-pt python=3.9 -y +conda install pytorch torchvision torchaudio pytorch-cuda=12.1 -c pytorch -c nvidia + +# tf需要安装 CUDA 和 cuDNN +conda install cudatoolkit=11.8 cudnn=8.9 -c nvidia -y + +pip install tensorflow +pip install -r requirements.txt +``` + ## 安装graphviz - 绘制模型图 ```shell brew install graphviz diff --git a/lab/9_CNN-MNIST.ipynb b/lab/9_CNN-MNIST.ipynb new file mode 100644 index 0000000..a291974 --- /dev/null +++ b/lab/9_CNN-MNIST.ipynb @@ -0,0 +1,325 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# CNN实现MNIST手写数字识别" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "d:\\Users\\17214\\miniconda3\\envs\\ail-tf\\lib\\site-packages\\keras\\src\\layers\\convolutional\\base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead.\n", + " super().__init__(activity_regularizer=activity_regularizer, **kwargs)\n" + ] + }, + { + "data": { + "text/html": [ + "
Model: \"sequential\"\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1mModel: \"sequential\"\u001b[0m\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n",
+       "┃ Layer (type)                     Output Shape                  Param # ┃\n",
+       "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n",
+       "│ conv2d (Conv2D)                 │ (None, 26, 26, 32)     │           320 │\n",
+       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+       "│ max_pooling2d (MaxPooling2D)    │ (None, 13, 13, 32)     │             0 │\n",
+       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+       "│ conv2d_1 (Conv2D)               │ (None, 11, 11, 64)     │        18,496 │\n",
+       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+       "│ max_pooling2d_1 (MaxPooling2D)  │ (None, 5, 5, 64)       │             0 │\n",
+       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+       "│ flatten (Flatten)               │ (None, 1600)           │             0 │\n",
+       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+       "│ dense (Dense)                   │ (None, 64)             │       102,464 │\n",
+       "├─────────────────────────────────┼────────────────────────┼───────────────┤\n",
+       "│ dense_1 (Dense)                 │ (None, 10)             │           650 │\n",
+       "└─────────────────────────────────┴────────────────────────┴───────────────┘\n",
+       "
\n" + ], + "text/plain": [ + "┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n", + "┃\u001b[1m \u001b[0m\u001b[1mLayer (type) \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m Param #\u001b[0m\u001b[1m \u001b[0m┃\n", + "┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n", + "│ conv2d (\u001b[38;5;33mConv2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m26\u001b[0m, \u001b[38;5;34m26\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m320\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ max_pooling2d (\u001b[38;5;33mMaxPooling2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m13\u001b[0m, \u001b[38;5;34m13\u001b[0m, \u001b[38;5;34m32\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ conv2d_1 (\u001b[38;5;33mConv2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m11\u001b[0m, \u001b[38;5;34m11\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m18,496\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ max_pooling2d_1 (\u001b[38;5;33mMaxPooling2D\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m5\u001b[0m, \u001b[38;5;34m5\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ flatten (\u001b[38;5;33mFlatten\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m1600\u001b[0m) │ \u001b[38;5;34m0\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ dense (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m64\u001b[0m) │ \u001b[38;5;34m102,464\u001b[0m │\n", + "├─────────────────────────────────┼────────────────────────┼───────────────┤\n", + "│ dense_1 (\u001b[38;5;33mDense\u001b[0m) │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m10\u001b[0m) │ \u001b[38;5;34m650\u001b[0m │\n", + "└─────────────────────────────────┴────────────────────────┴───────────────┘\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Total params: 121,930 (476.29 KB)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Total params: \u001b[0m\u001b[38;5;34m121,930\u001b[0m (476.29 KB)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Trainable params: 121,930 (476.29 KB)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m121,930\u001b[0m (476.29 KB)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
 Non-trainable params: 0 (0.00 B)\n",
+       "
\n" + ], + "text/plain": [ + "\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m0\u001b[0m (0.00 B)\n" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/10\n", + "\u001b[1m375/375\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m7s\u001b[0m 15ms/step - accuracy: 0.8320 - loss: 0.5733 - val_accuracy: 0.9737 - val_loss: 0.0860\n", + "Epoch 2/10\n", + "\u001b[1m375/375\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 14ms/step - accuracy: 0.9763 - loss: 0.0743 - val_accuracy: 0.9840 - val_loss: 0.0529\n", + "Epoch 3/10\n", + "\u001b[1m375/375\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 14ms/step - accuracy: 0.9853 - loss: 0.0478 - val_accuracy: 0.9849 - val_loss: 0.0505\n", + "Epoch 4/10\n", + "\u001b[1m375/375\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 14ms/step - accuracy: 0.9886 - loss: 0.0364 - val_accuracy: 0.9877 - val_loss: 0.0430\n", + "Epoch 5/10\n", + "\u001b[1m375/375\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 14ms/step - accuracy: 0.9907 - loss: 0.0282 - val_accuracy: 0.9888 - val_loss: 0.0394\n", + "Epoch 6/10\n", + "\u001b[1m375/375\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 14ms/step - accuracy: 0.9933 - loss: 0.0229 - val_accuracy: 0.9872 - val_loss: 0.0441\n", + "Epoch 7/10\n", + "\u001b[1m375/375\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 14ms/step - accuracy: 0.9940 - loss: 0.0187 - val_accuracy: 0.9872 - val_loss: 0.0424\n", + "Epoch 8/10\n", + "\u001b[1m375/375\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 14ms/step - accuracy: 0.9955 - loss: 0.0148 - val_accuracy: 0.9887 - val_loss: 0.0426\n", + "Epoch 9/10\n", + "\u001b[1m375/375\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 14ms/step - accuracy: 0.9954 - loss: 0.0145 - val_accuracy: 0.9862 - val_loss: 0.0500\n", + "Epoch 10/10\n", + "\u001b[1m375/375\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 14ms/step - accuracy: 0.9970 - loss: 0.0099 - val_accuracy: 0.9872 - val_loss: 0.0522\n", + "\u001b[1m313/313\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 3ms/step - accuracy: 0.9868 - loss: 0.0476\n", + "accuracy: 0.9899" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING:absl:You are saving your model as an HDF5 file via `model.save()` or `keras.saving.save_model(model)`. This file format is considered legacy. We recommend using instead the native Keras format, e.g. `model.save('my_model.keras')` or `keras.saving.save_model(model, 'my_model.keras')`. \n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "模型已保存到./models/mnist_model_cnn_tf.h5\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import tensorflow as tf\n", + "import tensorflow.keras as keras\n", + "from keras import datasets,layers\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# 加载mnist数据集\n", + "(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()\n", + "\n", + "x_train = x_train.reshape(-1,28,28,1)/255.0\n", + "x_test = x_test.reshape(-1,28,28,1)/255.0\n", + "\n", + "y_train = keras.utils.to_categorical(y_train,10)\n", + "y_test = keras.utils.to_categorical(y_test,10)\n", + "\n", + "model = keras.Sequential([\n", + " layers.Conv2D(32,(3,3),activation='relu',input_shape=(28,28,1)), #28-3+1/1 + 1 = 26,32\n", + " layers.MaxPooling2D((2,2)), # 26/2=13,32\n", + " layers.Conv2D(64,(3,3),activation='relu'), # 13-3+1/1 + 1 = 11,64\n", + " layers.MaxPooling2D((2,2)), # 11/2 = 6,64\n", + " layers.Flatten(), # 6*6*64 = 2304\n", + " layers.Dense(64,activation='relu'),\n", + " layers.Dense(10,activation='softmax')\n", + "])\n", + "\n", + "model.summary()\n", + "\n", + "model.compile(optimizer='adam',\n", + " loss='categorical_crossentropy',\n", + " metrics=['accuracy'])\n", + "\n", + "history = model.fit(x_train,y_train,\n", + " batch_size=128,\n", + " epochs=10,\n", + " validation_split=0.2)\n", + "\n", + "test_loss,test_acc = model.evaluate(x_test,y_test)\n", + "print(f'accuracy: {test_acc:.4f}')\n", + "\n", + "model.save('./models/mnist_model_cnn_tf.h5') # 保存为HDF5格式\n", + "print(\"模型已保存到./models/mnist_model_cnn_tf.h5\")\n", + "\n", + "plt.subplot(1, 2, 1)\n", + "plt.plot(history.history['accuracy'], label='train accuracy')\n", + "plt.plot(history.history['val_accuracy'], label='verify accuracy')\n", + "plt.title('accuracy')\n", + "plt.xlabel('Epoch')\n", + "plt.ylabel('Accuracy')\n", + "plt.legend()\n", + "\n", + "plt.subplot(1, 2, 2)\n", + "plt.plot(history.history['loss'], label='train loss')\n", + "plt.plot(history.history['val_loss'], label='val loss')\n", + "plt.title('loss')\n", + "plt.xlabel('Epoch')\n", + "plt.ylabel('Loss')\n", + "plt.legend()\n", + "\n", + "plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING:absl:Compiled the loaded model, but the compiled metrics have yet to be built. `model.compile_metrics` will be empty until you train or evaluate the model.\n" + ] + }, + { + "data": { + "image/png": "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0tLS5IYbbjCX6oqNjZWhQ4fK9u3bfeYpKiqSlJQUadCggdStW1dGjBghBw4ckFDbDr17975gfxg3bpwEkioRQO+++65MnjzZjG3//PPPpUuXLjJgwAA5ePCghJqrrrpK9u/f750++ugjCXaFhYXmb64/Qkoze/Zsefnll2XevHmyadMmqVOnjtk/9EAUSttBaeAU3z8WLVokwWTdunUmXDZu3CgrV66U06dPS//+/c228Zg0aZIsX75c0tPTzfx6bcnhw4dLqG0HlZyc7LM/6L+VgOJUAd26dXNSUlK8z8+ePeskJCQ4aWlpTiiZMWOG06VLFyeU6S67ZMkS7/Nz5845cXFxzrPPPut9LS8vz4mIiHAWLVrkhMp2UElJSc5dd93lhJKDBw+abbFu3Trv375mzZpOenq6d55vvvnGzLNhwwYnVLaDuuWWW5yHH37YCWQBXwM6deqUbN682TSrFL9gqT7fsGGDhBptWtImmNatW8t9990nu3fvllCWk5Mjubm5PvuHXgRRm2lDcf9Yu3ataZK58sorZfz48XL48GEJZvn5+eYxJibGPOqxQmsDxfcHbaZu3rx5UO8P+SW2g8fChQulYcOG0qlTJ0lNTZXjx49LIAm4q2GXdOjQITl79qw0btzY53V9/u2330oo0YPqggULzMFFq9OzZs2Snj17yrZt20xbcCjS8FGl7R+e90KFNr9pU1OrVq1k586d8vjjj8ugQYPMgbd69eoSbPTWLRMnTpQePXqYA6zSv3l4eLhER0eHzP5wrpTtoO69915p0aKF+cG6detW+fWvf236id5//30JFAEfQPgvPZh4dO7c2QSS7mDvvfeejBkzxuq6wb6RI0d6///qq682+0ibNm1Mrahv374SbLQPRH98hUI/qD/bYezYsT77gw7S0f1Af5zofhEIAr4JTquP+uut5CgWfR4XFyehTH/ltW/fXrKzsyVUefYB9o8LaTOt/vsJxv1jwoQJsmLFClmzZo3P/cP0b67N9nl5eSGxP0woYzuURn+wqkDaHwI+gLQ63bVrV8nMzPSpcurzxMRECWXHjh0zv2b0l02o0uYmPbAU3z/0jpA6Gi7U94+9e/eaPqBg2j90/IUedJcsWSKrV682f//i9FhRs2ZNn/1Bm520rzSY9gfnEtuhNFu2bDGPAbU/OFXA4sWLzaimBQsWOF9//bUzduxYJzo62snNzXVCySOPPOKsXbvWycnJcT7++GOnX79+TsOGDc0ImGB29OhR54svvjCT7rLPP/+8+f9du3aZ93/3u9+Z/WHZsmXO1q1bzUiwVq1aOSdOnHBCZTvoe48++qgZ6aX7x6pVq5zrrrvOadeunVNUVOQEi/HjxztRUVHm38H+/fu90/Hjx73zjBs3zmnevLmzevVqJysry0lMTDRTMBl/ie2QnZ3tPPHEE+b76/6g/zZat27t9OrVywkkVSKA1CuvvGJ2qvDwcDMse+PGjU6oueeee5z4+HizDZo0aWKe644W7NasWWMOuCUnHXbsGYo9bdo0p3HjxuaHSt++fZ3t27c7obQd9MDTv39/p1GjRmYYcosWLZzk5OSg+5FW2vfXaf78+d559IfHgw8+6NSvX9+54oornGHDhpmDcyhth927d5uwiYmJMf8m2rZt60yZMsXJz893Agn3AwIAWBHwfUAAgOBEAAEArCCAAABWEEAAACsIIACAFQQQAMAKAggAYAUBBACwggACAFhBAAEArCCAAABiw/8D/wAmzXe/3TEAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "预处理后的数据范围: 0.12156863 0.83137256\n", + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 97ms/step\n", + "预测概率分布: [[3.0960881e-09 1.5032079e-09 9.9999988e-01 7.3625035e-09 2.2941347e-09\n", + " 3.6706155e-12 2.5781807e-12 7.7586833e-08 4.7858329e-08 1.4447438e-10]]\n", + "预测结果:2\n" + ] + } + ], + "source": [ + "# 测试tf训练的手写数据识别\n", + "import tensorflow as tf\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "# 加载模型\n", + "model = tf.keras.models.load_model('./models/mnist_model_cnn_tf.h5')\n", + "\n", + "# 加载并预处理图片\n", + "image_path = './test/2.png'\n", + "image = tf.keras.preprocessing.image.load_img(image_path, target_size=(28, 28), color_mode='grayscale')\n", + "image = tf.keras.preprocessing.image.img_to_array(image)\n", + "\n", + "# 可视化预处理后的图片\n", + "plt.imshow(image, cmap='gray')\n", + "plt.title('Processed Image')\n", + "plt.show()\n", + "\n", + "# 进一步处理\n", + "image = image.reshape(-1, 28 , 28, 1) / 255.0\n", + "\n", + "# 打印预处理后的数据\n", + "print(\"预处理后的数据范围:\", np.min(image), np.max(image))\n", + "\n", + "# 进行预测\n", + "predictions = model.predict(image)\n", + "print(\"预测概率分布:\", predictions)\n", + "\n", + "# 获取预测结果\n", + "predicted_class = tf.argmax(predictions, axis=1).numpy()[0]\n", + "print(f\"预测结果:{predicted_class}\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "ail-tf", + "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.10.16" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/test/tf-cuda.py b/test/tf-cuda.py new file mode 100644 index 0000000..daf2df9 --- /dev/null +++ b/test/tf-cuda.py @@ -0,0 +1,28 @@ +import tensorflow as tf + +# 打印 TensorFlow 版本 +print("TensorFlow 版本:", tf.__version__) + +# 检查 CUDA 是否可用 +cuda_available = tf.test.is_built_with_cuda() +print(f"CUDA 支持: {cuda_available}") + +# 检查 GPU 是否可用 +gpu_available = tf.config.list_physical_devices('GPU') +print(f"GPU 可用: {gpu_available}") + +# 打印可用设备 +print("\n可用设备:") +for device in tf.config.list_physical_devices(): + print(device) + +# 如果 GPU 可用,打印详细信息 +gpus = tf.config.list_physical_devices('GPU') +if gpus: + print("\nGPU 详细信息:") + for gpu in gpus: + print(gpu) + print("设备名称:", gpu.name) + print("设备类型:", gpu.device_type) +else: + print("\n未检测到GPU设备") \ No newline at end of file diff --git a/test/torch-cuda.py b/test/torch-cuda.py new file mode 100644 index 0000000..cd73a5d --- /dev/null +++ b/test/torch-cuda.py @@ -0,0 +1,20 @@ +import torch + +# 打印 PyTorch 版本 +print("PyTorch 版本:", torch.__version__) + +# 检查 CUDA 是否可用 +cuda_available = torch.cuda.is_available() +print(f"CUDA 可用: {cuda_available}") + +# 如果 CUDA 可用,打印 GPU 信息 +if cuda_available: + print("\nGPU 详细信息:") + print("GPU 数量:", torch.cuda.device_count()) + print("当前 GPU:", torch.cuda.current_device()) + print("GPU 名称:", torch.cuda.get_device_name(0)) + print("GPU 内存:") + print(" 已分配:", torch.cuda.memory_allocated()) + print(" 保留:", torch.cuda.memory_reserved()) +else: + print("\n未检测到GPU设备") \ No newline at end of file