{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport numpy as npy\nimport pandas as pd","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-10-19T08:01:46.461085Z","iopub.execute_input":"2022-10-19T08:01:46.461618Z","iopub.status.idle":"2022-10-19T08:01:46.486571Z","shell.execute_reply.started":"2022-10-19T08:01:46.461504Z","shell.execute_reply":"2022-10-19T08:01:46.485551Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(\"../input/landmark-retrieval-2020/train.csv\")\nprint(df.columns)\ndf.shape","metadata":{"execution":{"iopub.status.busy":"2022-10-19T08:01:48.682672Z","iopub.execute_input":"2022-10-19T08:01:48.683106Z","iopub.status.idle":"2022-10-19T08:01:50.570322Z","shell.execute_reply.started":"2022-10-19T08:01:48.683069Z","shell.execute_reply":"2022-10-19T08:01:50.568860Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[\"landmark_id\"].value_counts().index","metadata":{"execution":{"iopub.status.busy":"2022-10-19T08:01:51.632986Z","iopub.execute_input":"2022-10-19T08:01:51.633406Z","iopub.status.idle":"2022-10-19T08:01:51.701657Z","shell.execute_reply.started":"2022-10-19T08:01:51.633371Z","shell.execute_reply":"2022-10-19T08:01:51.700239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.scatter(df[\"landmark_id\"].value_counts().index, npy.log(df[\"landmark_id\"].value_counts().values), marker=\"+\")","metadata":{"execution":{"iopub.status.busy":"2022-10-19T08:10:21.971054Z","iopub.execute_input":"2022-10-19T08:10:21.971468Z","iopub.status.idle":"2022-10-19T08:10:22.377175Z","shell.execute_reply.started":"2022-10-19T08:10:21.971416Z","shell.execute_reply":"2022-10-19T08:10:22.375414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split\nX = df[\"id\"].values\nY = df[\"landmark_id\"].values\n\nx_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.5, random_state=42)\n\ntrain_df = pd.DataFrame({\n    \"id\": x_train,\n    \"landmark_id\": y_train\n})\n\ntest_df = pd.DataFrame({\n    \"id\": x_test,\n    \"landmark_id\": y_test\n})\n\ntrain_df","metadata":{"execution":{"iopub.status.busy":"2022-10-19T07:24:26.557483Z","iopub.execute_input":"2022-10-19T07:24:26.557757Z","iopub.status.idle":"2022-10-19T07:24:27.309982Z","shell.execute_reply.started":"2022-10-19T07:24:26.557732Z","shell.execute_reply":"2022-10-19T07:24:27.309056Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sklearn\nimport tensorflow as tf\nimport tensorflow.keras as keras","metadata":{"execution":{"iopub.status.busy":"2022-10-19T07:24:27.315241Z","iopub.execute_input":"2022-10-19T07:24:27.317881Z","iopub.status.idle":"2022-10-19T07:24:32.064042Z","shell.execute_reply.started":"2022-10-19T07:24:27.317841Z","shell.execute_reply":"2022-10-19T07:24:32.063041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.utils import Sequence, to_categorical\n\nDATASET_ROOT = \"../input/landmark-retrieval-2020/train\"\nNUM_OF_CLASSES = df[\"landmark_id\"].max()\n\nclass GoogleLandmarkDataset(Sequence):\n    # 构造函数，传入csv文件的DataFrame，设置batch_size和图像大小\n    def __init__(self, data_df, batch_size=32, img_size=(224, 224)):\n        self.data_df = data_df\n        self.num_of_data = data_df.shape[0]\n        self.batch_size = batch_size\n        self.height, self.width = img_size\n        self.on_epoch_end()\n    \n    # tensorflow要求item返回一个batch，所以len是一个epoch需要多少batch\n    def __len__(self):\n        return int(self.num_of_data / self.batch_size)\n    \n    # 图像id转化成图像路径\n    def id_to_path(self, idx):\n        return \"{}/{}/{}/{}/{}.jpg\".format(DATASET_ROOT, idx[0], idx[1], idx[2], idx)\n    \n    def on_epoch_end(self):\n        self.data_df = sklearn.utils.shuffle(self.data_df) #随机打乱\n    \n    # 一个batch的id的图像读取出来\n    def get_img_batch(self, batch_img_id):\n        batch_img = []\n        for idx in batch_img_id:\n            path = self.id_to_path(idx) # id转路径\n            img = tf.io.read_file(path) # 从路径读图\n            img = tf.image.decode_jpeg(img, channels=3) # 图片解码成jpg\n            img = tf.image.resize(img, [self.height, self.width]) # 统一图像大小\n            img /= 255.0 # 放缩到0~1\n            img = tf.image.random_flip_left_right(img) # 随机翻转做个数据增广\n            batch_img.append(img)\n        return batch_img\n    \n    # 给出一个batch和数据和标签，标签用one-hot编码\n    def __getitem__(self, idx):\n        l = idx * self.batch_size\n        r = (idx+1) * self.batch_size\n        batch_img_id = self.data_df[\"id\"][l:r].values # 迭代过程只需要df中的值所以用values，也方便迭代，下同\n        batch_label = self.data_df[\"landmark_id\"][l:r].values\n        \n        batch_img = self.get_img_batch(batch_img_id) # 从id读取图片\n        batch_label_one_hot = to_categorical(batch_label, NUM_OF_CLASSES) # 将序号编码转换成one-hot编码，一行对应一个sample\n        return  npy.array(batch_img), npy.array(batch_label_one_hot)","metadata":{"execution":{"iopub.status.busy":"2022-10-19T07:24:32.065499Z","iopub.execute_input":"2022-10-19T07:24:32.066133Z","iopub.status.idle":"2022-10-19T07:24:32.083360Z","shell.execute_reply.started":"2022-10-19T07:24:32.066094Z","shell.execute_reply":"2022-10-19T07:24:32.081399Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 256 # 再大就炸显存了\nIMG_SIZE = (224, 224)\n\ntrain_ds = GoogleLandmarkDataset(train_df, batch_size=BATCH_SIZE, img_size=IMG_SIZE)\ntest_ds = GoogleLandmarkDataset(test_df, batch_size=BATCH_SIZE, img_size=IMG_SIZE)","metadata":{"execution":{"iopub.status.busy":"2022-10-19T07:26:35.723837Z","iopub.execute_input":"2022-10-19T07:26:35.724212Z","iopub.status.idle":"2022-10-19T07:26:35.949383Z","shell.execute_reply.started":"2022-10-19T07:26:35.724166Z","shell.execute_reply":"2022-10-19T07:26:35.948361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"aaaa = test_ds.__getitem__(0)[0][0]\nplt.imshow(aaaa)","metadata":{"execution":{"iopub.status.busy":"2022-10-19T07:26:38.017839Z","iopub.execute_input":"2022-10-19T07:26:38.018216Z","iopub.status.idle":"2022-10-19T07:26:47.208020Z","shell.execute_reply.started":"2022-10-19T07:26:38.018169Z","shell.execute_reply":"2022-10-19T07:26:47.207106Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n下面开始炼丹","metadata":{}},{"cell_type":"code","source":"# # 一些使用TPU的代码\n# # detect and init the TPU\n# tpu = tf.distribute.cluster_resolver.TPUClusterResolver.connect()\n\n# # instantiate a distribution strategy\n# tpu_strategy = tf.distribute.experimental.TPUStrategy(tpu)","metadata":{"execution":{"iopub.status.busy":"2022-10-19T07:24:40.548313Z","iopub.execute_input":"2022-10-19T07:24:40.548943Z","iopub.status.idle":"2022-10-19T07:24:40.553645Z","shell.execute_reply.started":"2022-10-19T07:24:40.548904Z","shell.execute_reply":"2022-10-19T07:24:40.552512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"base_model = keras.applications.resnet_v2.ResNet152V2(\n    include_top=False, \n    weights='imagenet', \n    input_shape=(224, 224, 3)\n)\n\nbase_model.trainable = False\n\ninputs = keras.Input((224, 224, 3))\nx = base_model(inputs, training=False)\nx = keras.layers.GlobalAveragePooling2D()(x)\noutputs = keras.layers.Dense(NUM_OF_CLASSES)(x)\n\nmodel = keras.Model(inputs, outputs)\n\nmodel.compile(\n    optimizer=\"Adam\",\n    loss=\"categorical_crossentropy\",\n    metrics=[\"categorical_accuracy\"]\n)\n\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2022-10-19T07:26:51.227739Z","iopub.execute_input":"2022-10-19T07:26:51.228111Z","iopub.status.idle":"2022-10-19T07:26:56.295908Z","shell.execute_reply.started":"2022-10-19T07:26:51.228071Z","shell.execute_reply":"2022-10-19T07:26:56.294811Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(\n    train_ds, \n    epochs=10,\n    validation_data=test_ds\n)","metadata":{"execution":{"iopub.status.busy":"2022-10-19T07:26:59.028097Z","iopub.execute_input":"2022-10-19T07:26:59.029111Z","iopub.status.idle":"2022-10-19T07:28:01.098229Z","shell.execute_reply.started":"2022-10-19T07:26:59.029074Z","shell.execute_reply":"2022-10-19T07:28:01.096848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!nvidia-smi","metadata":{"execution":{"iopub.status.busy":"2022-10-19T07:29:11.626155Z","iopub.execute_input":"2022-10-19T07:29:11.627185Z","iopub.status.idle":"2022-10-19T07:29:12.713618Z","shell.execute_reply.started":"2022-10-19T07:29:11.627149Z","shell.execute_reply":"2022-10-19T07:29:12.712406Z"},"trusted":true},"execution_count":null,"outputs":[]}]}