{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":3004,"databundleVersionId":861823,"sourceType":"competition"},{"sourceId":26140,"sourceType":"modelInstanceVersion","modelInstanceId":22003,"modelId":3301}],"dockerImageVersionId":31153,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 升级 transformers 库以支持 vaultgemma 架构\n# 使用 pip install -q 表示“静默安装”，减少输出，保持 Notebook 界面整洁\n!pip install -q --upgrade transformers\n\n# 检查升级后的版本（可选）\nimport transformers\nprint(f\"Transformers version after upgrade: {transformers.__version__}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-28T15:51:55.094047Z","iopub.execute_input":"2025-10-28T15:51:55.094384Z","iopub.status.idle":"2025-10-28T15:52:22.627474Z","shell.execute_reply.started":"2025-10-28T15:51:55.094359Z","shell.execute_reply":"2025-10-28T15:52:22.626219Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-28T15:52:22.629221Z","iopub.execute_input":"2025-10-28T15:52:22.629687Z","iopub.status.idle":"2025-10-28T15:52:23.108080Z","shell.execute_reply.started":"2025-10-28T15:52:22.629664Z","shell.execute_reply":"2025-10-28T15:52:23.107168Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout\nfrom tensorflow.keras.utils import to_categorical\n\n# --- 环境设置提醒 (在 Notebook 中，请确保这些命令已在单独单元格中运行) ---\n# !pip install -q --upgrade transformers\n# !pip install -q git+https://github.com/huggingface/transformers.git\n\n# --- 1. 定义模型和数据文件的路径 ---\n# 模型路径 (Gemma 1B) - 尽管加载失败，仍保留路径定义\nMODEL_PATH = \"/kaggle/input/vaultgemma/transformers/1b/1\"\n\n# 数字识别数据 - 来自 'digit-recognizer-challenge' (主要使用这个数据集)\nCHALLENGE_TRAIN_PATH = \"/kaggle/input/digit-recognizer/train.csv\"\nCHALLENGE_TEST_PATH = \"/kaggle/input/digit-recognizer/test.csv\"\n\nprint(\"✅ 所有输入路径已定义。\")\nprint(\"-\" * 40)\n\n\n# --- 2. 加载数据 ---\nprint(\"📊 正在加载数字识别数据...\")\ntry:\n    df_train_challenge = pd.read_csv(CHALLENGE_TRAIN_PATH)\n    df_test_challenge = pd.read_csv(CHALLENGE_TEST_PATH)\n    print(f\"  - 训练集形状: {df_train_challenge.shape}\")\n    print(f\"  - 测试集形状: {df_test_challenge.shape}\")\nexcept FileNotFoundError as e:\n    print(f\"❌ 错误：无法找到数据文件。请检查路径。错误信息: {e}\")\n    exit() # 如果数据加载失败，终止脚本\n\nprint(\"-\" * 40)\n\n\n# --- 3. 尝试加载 Gemma 模型 (当前已确认失败，但保留代码块) ---\nprint(\"🧠 正在尝试加载 Gemma 模型...\")\ntry:\n    from transformers import AutoModelForCausalLM, AutoTokenizer\n    # 强制将模型路径添加到系统路径，并尝试使用 trust_remote_code\n    import sys\n    sys.path.append(MODEL_PATH) \n    \n    tokenizer = AutoTokenizer.from_pretrained(MODEL_PATH, trust_remote_code=True)\n    model_gemma = AutoModelForCausalLM.from_pretrained(MODEL_PATH, trust_remote_code=True)\n    print(\"  - Gemma 模型和分词器加载成功。\")\n\nexcept Exception as e:\n    # 忽略此警告，继续执行数字识别任务\n    print(f\"⚠️ 警告：Gemma 模型加载失败 (预期错误)。错误信息: {e.args[0][:120]}...\")\n\nprint(\"-\" * 40)\n\n\n# --- 4. 数字识别数据预处理 ---\nprint(\"⚙️ 正在进行数据预处理...\")\n\n# 4.1 分离特征 X 和标签 y\nX_train = df_train_challenge.drop('label', axis=1).values # 特征 (像素数据)\ny_train = df_train_challenge['label'].values             # 标签 (数字 0-9)\nX_test = df_test_challenge.values                        # 测试集特征\n\n# 4.2 数据标准化/归一化 (Normalization)\nX_train = X_train.astype('float32') / 255.0\nX_test = X_test.astype('float32') / 255.0\n\n# 4.3 重塑数据为图像矩阵 (为 CNN 模型准备)\n# 形状: (样本数, 高度, 宽度, 通道数)\nX_train = X_train.reshape(-1, 28, 28, 1)\nX_test = X_test.reshape(-1, 28, 28, 1)\n\n# 4.4 对标签进行独热编码 (One-Hot Encoding)\ny_train_encoded = to_categorical(y_train, num_classes=10)\n\nprint(\"✅ 数据预处理完成，数据形状已调整。\")\nprint(f\"X_train 最终形状: {X_train.shape}, y_train_encoded 最终形状: {y_train_encoded.shape}\")\n\nprint(\"-\" * 40)\n\n\n# --- 5. 构建并编译 CNN 模型 ---\nprint(\"🏗️ 正在构建和编译 CNN 模型...\")\ncnn_model = Sequential([\n    # 卷积层 1\n    Conv2D(32, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)),\n    MaxPooling2D(pool_size=(2, 2)),\n    \n    # 卷积层 2\n    Conv2D(64, kernel_size=(3, 3), activation='relu'),\n    MaxPooling2D(pool_size=(2, 2)),\n    \n    # 展平层\n    Flatten(),\n    \n    # 全连接层\n    Dense(128, activation='relu'),\n    Dropout(0.5), \n    \n    # 输出层\n    Dense(10, activation='softmax')\n])\n\ncnn_model.compile(optimizer='adam', \n                  loss='categorical_crossentropy', \n                  metrics=['accuracy'])\n\nprint(\"✅ CNN 模型架构已定义并编译。\")\ncnn_model.summary()\n\nprint(\"-\" * 40)\n\n\n# --- 6. 模型训练 ---\nprint(\"🏃 正在开始模型训练 (10 Epochs)...\")\nhistory = cnn_model.fit(\n    X_train, y_train_encoded,\n    batch_size=128,      \n    epochs=10,           \n    validation_split=0.1 \n)\nprint(\"\\n🎉 模型训练成功结束。\")\n\nprint(\"-\" * 40)\n\n\n# --- 7. 生成 Kaggle 提交文件 ---\nprint(\"📝 正在生成 Kaggle 提交文件...\")\n\n# 7.1 使用模型进行预测\n# model.predict() 会返回一个概率矩阵\npredictions_prob = cnn_model.predict(X_test)\n\n# 7.2 获取最终的预测标签 (数字)\n# np.argmax(axis=1) 获取概率最高的索引\npredictions = np.argmax(predictions_prob, axis=1)\n\n# 7.3 创建 ImageId 序列 (从 1 开始)\nimage_ids = np.arange(1, len(predictions) + 1)\n\n# 7.4 创建 DataFrame\nsubmission_df = pd.DataFrame({\n    'ImageId': image_ids,\n    'Label': predictions\n})\n\n# 7.5 导出 CSV 文件\nSUBMISSION_FILE_PATH = 'submission.csv'\nsubmission_df.to_csv(SUBMISSION_FILE_PATH, index=False)\n\nprint(f\"\\n✅ 提交文件生成成功！文件名称: {SUBMISSION_FILE_PATH}\")\nprint(\"\\n--- 提交文件预览 (前 5 行) ---\")\nprint(submission_df.head())\nprint(\"-\" * 40)\nprint(\"✨ 整个程式流程已执行完毕。\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-28T15:52:23.109080Z","iopub.execute_input":"2025-10-28T15:52:23.109602Z","iopub.status.idle":"2025-10-28T15:55:45.601785Z","shell.execute_reply.started":"2025-10-28T15:52:23.109579Z","shell.execute_reply":"2025-10-28T15:55:45.600793Z"}},"outputs":[],"execution_count":null}]}