{"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":"gpu","dataSources":[{"sourceId":3649,"databundleVersionId":46718,"isSourceIdPinned":false,"sourceType":"competition"},{"sourceId":286452148,"sourceType":"kernelVersion"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"! pip install -U 'tensorflow[and-cuda]'","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:49:52.622934Z","iopub.execute_input":"2025-12-16T06:49:52.623310Z","iopub.status.idle":"2025-12-16T06:51:34.294193Z","shell.execute_reply.started":"2025-12-16T06:49:52.623281Z","shell.execute_reply":"2025-12-16T06:51:34.291165Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"! pip install git+https://github.com/darecophoenixx/wordroid.sblo.jp","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:51:34.299134Z","iopub.execute_input":"2025-12-16T06:51:34.301734Z","iopub.status.idle":"2025-12-16T06:51:59.040834Z","shell.execute_reply.started":"2025-12-16T06:51:34.301590Z","shell.execute_reply":"2025-12-16T06:51:59.039014Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from keras_ex.gkernel import GaussianKernel, GaussianKernel2, GaussianKernel3","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:51:59.042703Z","iopub.execute_input":"2025-12-16T06:51:59.043128Z","iopub.status.idle":"2025-12-16T06:52:12.253461Z","shell.execute_reply.started":"2025-12-16T06:51:59.043082Z","shell.execute_reply":"2025-12-16T06:52:12.252283Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%matplotlib inline\nfrom IPython.display import SVG\nfrom tensorflow.keras.utils import plot_model, to_categorical, Sequence","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:52:12.255663Z","iopub.execute_input":"2025-12-16T06:52:12.256284Z","iopub.status.idle":"2025-12-16T06:52:12.263798Z","shell.execute_reply.started":"2025-12-16T06:52:12.256254Z","shell.execute_reply":"2025-12-16T06:52:12.262671Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ! pip install libarchive-c","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:52:12.264880Z","iopub.execute_input":"2025-12-16T06:52:12.265219Z","iopub.status.idle":"2025-12-16T06:52:12.290198Z","shell.execute_reply.started":"2025-12-16T06:52:12.265188Z","shell.execute_reply":"2025-12-16T06:52:12.289113Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"! pip install py7zr","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:52:12.291488Z","iopub.execute_input":"2025-12-16T06:52:12.291963Z","iopub.status.idle":"2025-12-16T06:52:19.117941Z","shell.execute_reply.started":"2025-12-16T06:52:12.291934Z","shell.execute_reply":"2025-12-16T06:52:19.116765Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import py7zr\nfrom PIL import Image\nimport io","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:52:19.119339Z","iopub.execute_input":"2025-12-16T06:52:19.119779Z","iopub.status.idle":"2025-12-16T06:52:19.219709Z","shell.execute_reply.started":"2025-12-16T06:52:19.119728Z","shell.execute_reply":"2025-12-16T06:52:19.218758Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os.path\nimport sys\nimport re\nimport itertools\nimport csv\nimport datetime\nimport pickle\nfrom collections import defaultdict, Counter\nimport random\nimport gc\nimport zipfile\nimport warnings\n\nimport matplotlib.pyplot as plt\nfrom matplotlib.ticker import NullFormatter\nimport seaborn as sns\nimport pandas as pd\nimport numpy as np\nimport scipy\nimport gensim\nfrom scipy.sparse import linalg\nfrom sklearn.metrics import f1_score, classification_report, confusion_matrix\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import pairwise\nfrom sklearn.metrics import f1_score, classification_report, confusion_matrix\nfrom sklearn import decomposition\nfrom sklearn import mixture\nfrom sklearn import preprocessing\nfrom sklearn import cluster\nfrom sklearn import manifold\nimport networkx as nx\n\nimport tensorflow as tf","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:52:19.221056Z","iopub.execute_input":"2025-12-16T06:52:19.221444Z","iopub.status.idle":"2025-12-16T06:52:56.799009Z","shell.execute_reply.started":"2025-12-16T06:52:19.221409Z","shell.execute_reply":"2025-12-16T06:52:56.798043Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"! pip install japanize-matplotlib\n! pip install pyvis","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:52:56.800072Z","iopub.execute_input":"2025-12-16T06:52:56.801118Z","iopub.status.idle":"2025-12-16T06:53:08.819030Z","shell.execute_reply.started":"2025-12-16T06:52:56.801082Z","shell.execute_reply":"2025-12-16T06:53:08.817778Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from pyvis.network import Network\nimport japanize_matplotlib\nplt.rcParams['font.family']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:08.823027Z","iopub.execute_input":"2025-12-16T06:53:08.823365Z","iopub.status.idle":"2025-12-16T06:53:08.980869Z","shell.execute_reply.started":"2025-12-16T06:53:08.823329Z","shell.execute_reply":"2025-12-16T06:53:08.979943Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def hexbin(x, y, color, **kwargs):\n    cmap = sns.light_palette(color, as_cmap=True)\n    plt.hexbin(x, y, cmap=cmap, **kwargs)\ndef scatter(x, y, color, **kwargs):\n    plt.scatter(x, y, marker='.')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:08.981778Z","iopub.execute_input":"2025-12-16T06:53:08.982608Z","iopub.status.idle":"2025-12-16T06:53:08.988235Z","shell.execute_reply.started":"2025-12-16T06:53:08.982573Z","shell.execute_reply":"2025-12-16T06:53:08.987128Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tgt_dir = ''\ndir_name = 'img'\n\nimg_cnt = 0\ndef save_img():\n    global img_cnt\n    img_cnt += 1\n    img_name = 'img_{0:03}.png'.format(img_cnt)\n    img_name = os.path.join(tgt_dir, dir_name, img_name)\n    print(img_name)\n    plt.savefig(img_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:08.989264Z","iopub.execute_input":"2025-12-16T06:53:08.989919Z","iopub.status.idle":"2025-12-16T06:53:09.006109Z","shell.execute_reply.started":"2025-12-16T06:53:08.989890Z","shell.execute_reply":"2025-12-16T06:53:09.004869Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"! mkdir img","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:09.007103Z","iopub.execute_input":"2025-12-16T06:53:09.007403Z","iopub.status.idle":"2025-12-16T06:53:09.168184Z","shell.execute_reply.started":"2025-12-16T06:53:09.007378Z","shell.execute_reply":"2025-12-16T06:53:09.166822Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\", \"When grouping with\")\nwarnings.filterwarnings(\"ignore\", \"use_inf_as_na\")\nwarnings.filterwarnings(\"ignore\", \"The figure layout\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:09.169640Z","iopub.execute_input":"2025-12-16T06:53:09.170568Z","iopub.status.idle":"2025-12-16T06:53:09.176900Z","shell.execute_reply.started":"2025-12-16T06:53:09.170529Z","shell.execute_reply":"2025-12-16T06:53:09.175755Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# cifar-10","metadata":{}},{"cell_type":"code","source":"train_7z_file = \"/kaggle/input/cifar-10/train.7z\"\ntest_7z_file = \"/kaggle/input/cifar-10/test.7z\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:09.178316Z","iopub.execute_input":"2025-12-16T06:53:09.178590Z","iopub.status.idle":"2025-12-16T06:53:09.200752Z","shell.execute_reply.started":"2025-12-16T06:53:09.178567Z","shell.execute_reply":"2025-12-16T06:53:09.199454Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%time\nwith py7zr.SevenZipFile(train_7z_file, 'r') as archive:\n    archive.extractall(path=\".\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:09.202037Z","iopub.execute_input":"2025-12-16T06:53:09.202376Z","iopub.status.idle":"2025-12-16T06:53:37.043091Z","shell.execute_reply.started":"2025-12-16T06:53:09.202348Z","shell.execute_reply":"2025-12-16T06:53:37.042010Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_files = os.listdir('train/')\ntrain_files = sorted(train_files, key=lambda s: int(s.split('.')[0]))\nprint(len(train_files))\ntrain_files[:5]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:37.044097Z","iopub.execute_input":"2025-12-16T06:53:37.044387Z","iopub.status.idle":"2025-12-16T06:53:37.108186Z","shell.execute_reply.started":"2025-12-16T06:53:37.044355Z","shell.execute_reply":"2025-12-16T06:53:37.107278Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"trainImg_list = []\nfor ifile in train_files:\n    img = Image.open(f'train/{ifile}')\n    img_array = np.asarray(img)\n    trainImg_list.append(img_array)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:37.109335Z","iopub.execute_input":"2025-12-16T06:53:37.109759Z","iopub.status.idle":"2025-12-16T06:53:46.595168Z","shell.execute_reply.started":"2025-12-16T06:53:37.109723Z","shell.execute_reply":"2025-12-16T06:53:46.593648Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train0 = np.stack(trainImg_list).astype('float32') / 255.0\nx_train0.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:46.596360Z","iopub.execute_input":"2025-12-16T06:53:46.596731Z","iopub.status.idle":"2025-12-16T06:53:47.215354Z","shell.execute_reply.started":"2025-12-16T06:53:46.596694Z","shell.execute_reply":"2025-12-16T06:53:47.214418Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train1 = x_train0[:,:,::-1,:,]\nx_train1.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:47.216348Z","iopub.execute_input":"2025-12-16T06:53:47.216766Z","iopub.status.idle":"2025-12-16T06:53:47.222864Z","shell.execute_reply.started":"2025-12-16T06:53:47.216733Z","shell.execute_reply":"2025-12-16T06:53:47.221947Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_train = np.vstack([x_train0, x_train1])\nx_train.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:47.224123Z","iopub.execute_input":"2025-12-16T06:53:47.224436Z","iopub.status.idle":"2025-12-16T06:53:48.133210Z","shell.execute_reply.started":"2025-12-16T06:53:47.224392Z","shell.execute_reply":"2025-12-16T06:53:48.132419Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%time\nwith py7zr.SevenZipFile(test_7z_file, 'r') as archive:\n    archive.extractall(path=\".\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:53:48.134174Z","iopub.execute_input":"2025-12-16T06:53:48.134457Z","iopub.status.idle":"2025-12-16T06:56:26.188666Z","shell.execute_reply.started":"2025-12-16T06:53:48.134430Z","shell.execute_reply":"2025-12-16T06:56:26.187695Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"test_files = os.listdir('test/')\ntest_files = sorted(test_files, key=lambda s: int(s.split('.')[0]))\nprint(len(test_files))\ntest_files[:5]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:56:26.189964Z","iopub.execute_input":"2025-12-16T06:56:26.190325Z","iopub.status.idle":"2025-12-16T06:56:26.563602Z","shell.execute_reply.started":"2025-12-16T06:56:26.190290Z","shell.execute_reply":"2025-12-16T06:56:26.562777Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%time\ntestImg_list = []\nfor ifile in test_files:\n    img = Image.open(f'test/{ifile}')\n    img_array = np.asarray(img)\n    testImg_list.append(img_array)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:56:26.564659Z","iopub.execute_input":"2025-12-16T06:56:26.565091Z","iopub.status.idle":"2025-12-16T06:57:24.679071Z","shell.execute_reply.started":"2025-12-16T06:56:26.565058Z","shell.execute_reply":"2025-12-16T06:57:24.677840Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"x_test = np.stack(testImg_list).astype('float32') / 255.0\nx_test.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:24.680324Z","iopub.execute_input":"2025-12-16T06:57:24.680729Z","iopub.status.idle":"2025-12-16T06:57:28.522867Z","shell.execute_reply.started":"2025-12-16T06:57:24.680694Z","shell.execute_reply":"2025-12-16T06:57:28.521806Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_train_label = pd.read_csv('/kaggle/input/cifar-10/trainLabels.csv', index_col=0)\ndf_train_label","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:28.523993Z","iopub.execute_input":"2025-12-16T06:57:28.524460Z","iopub.status.idle":"2025-12-16T06:57:28.653393Z","shell.execute_reply.started":"2025-12-16T06:57:28.524427Z","shell.execute_reply":"2025-12-16T06:57:28.652348Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"id_key = dict([ee for ee in enumerate(np.unique(df_train_label.label.values))])\nid_key","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:28.654474Z","iopub.execute_input":"2025-12-16T06:57:28.655095Z","iopub.status.idle":"2025-12-16T06:57:28.690883Z","shell.execute_reply.started":"2025-12-16T06:57:28.655059Z","shell.execute_reply":"2025-12-16T06:57:28.689615Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"key_id = dict([(ee[1], ee[0]) for ee in enumerate(np.unique(df_train_label.label.values))])\nkey_id","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:28.700215Z","iopub.execute_input":"2025-12-16T06:57:28.700695Z","iopub.status.idle":"2025-12-16T06:57:28.739823Z","shell.execute_reply.started":"2025-12-16T06:57:28.700555Z","shell.execute_reply":"2025-12-16T06:57:28.738520Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_labels = [key_id[l] for l in df_train_label['label'].values]\ny_labels[:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:28.740972Z","iopub.execute_input":"2025-12-16T06:57:28.741277Z","iopub.status.idle":"2025-12-16T06:57:28.763262Z","shell.execute_reply.started":"2025-12-16T06:57:28.741252Z","shell.execute_reply":"2025-12-16T06:57:28.762100Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_labels2 = y_labels * 2\nprint(len(y_labels2))\ny_labels2[:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:28.764350Z","iopub.execute_input":"2025-12-16T06:57:28.764828Z","iopub.status.idle":"2025-12-16T06:57:28.789184Z","shell.execute_reply.started":"2025-12-16T06:57:28.764791Z","shell.execute_reply":"2025-12-16T06:57:28.788073Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"np.unique(y_labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:28.790252Z","iopub.execute_input":"2025-12-16T06:57:28.790557Z","iopub.status.idle":"2025-12-16T06:57:28.819982Z","shell.execute_reply.started":"2025-12-16T06:57:28.790526Z","shell.execute_reply":"2025-12-16T06:57:28.818898Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sampleSubmission = pd.read_csv('/kaggle/input/cifar-10/sampleSubmission.csv', index_col=0)\nsampleSubmission","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:28.820969Z","iopub.execute_input":"2025-12-16T06:57:28.821208Z","iopub.status.idle":"2025-12-16T06:57:28.927977Z","shell.execute_reply.started":"2025-12-16T06:57:28.821191Z","shell.execute_reply":"2025-12-16T06:57:28.926879Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img = Image.open('train/2811.png')\nimg\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:28.929126Z","iopub.execute_input":"2025-12-16T06:57:28.929472Z","iopub.status.idle":"2025-12-16T06:57:28.985445Z","shell.execute_reply.started":"2025-12-16T06:57:28.929442Z","shell.execute_reply":"2025-12-16T06:57:28.984022Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import imageio.v2 as imageio\n\nimg_array = imageio.imread(\"train/2811.png\")\nimg_array.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:28.986869Z","iopub.execute_input":"2025-12-16T06:57:28.987227Z","iopub.status.idle":"2025-12-16T06:57:29.088227Z","shell.execute_reply.started":"2025-12-16T06:57:28.987194Z","shell.execute_reply":"2025-12-16T06:57:29.087293Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.imshow(img_array)\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:29.089440Z","iopub.execute_input":"2025-12-16T06:57:29.089907Z","iopub.status.idle":"2025-12-16T06:57:29.438300Z","shell.execute_reply.started":"2025-12-16T06:57:29.089878Z","shell.execute_reply":"2025-12-16T06:57:29.437145Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img = Image.fromarray(img_array)\nimg\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:29.439516Z","iopub.execute_input":"2025-12-16T06:57:29.439907Z","iopub.status.idle":"2025-12-16T06:57:29.466096Z","shell.execute_reply.started":"2025-12-16T06:57:29.439877Z","shell.execute_reply":"2025-12-16T06:57:29.464947Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# #from tensorflow.keras.utils import PyDataset\n# from keras.utils import PyDataset\n\n# class CIFAR10PyDataset(PyDataset):\n\n#     def __init__(self, x_filename_list, y_class, batch_size=32, **kwargs):\n#         super().__init__(**kwargs)\n#         self.x, self.y = x_filename_list, y_class\n#         self.batch_size = batch_size\n\n#     def __len__(self):\n#         # Return number of batches.\n#         return int(np.ceil(len(self.x) / self.batch_size))\n\n#     def __getitem__(self, idx):\n#         # Return x, y for batch idx.\n#         low = idx * self.batch_size\n#         # Cap upper bound at array length; the last batch may be smaller\n#         # if the total number of items is not a multiple of batch size.\n#         high = min(low + self.batch_size, len(self.x))\n#         batch_x = self.x[low:high]\n#         batch_y = self.y[low:high]\n\n#         return (\n#             np.array([imageio.imread(f\"train/{file_name}\") / 255.0 for file_name in batch_x]),\n#             to_categorical(batch_y, num_classes=10)\n#         )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:29.467274Z","iopub.execute_input":"2025-12-16T06:57:29.467529Z","iopub.status.idle":"2025-12-16T06:57:29.473208Z","shell.execute_reply.started":"2025-12-16T06:57:29.467508Z","shell.execute_reply":"2025-12-16T06:57:29.471908Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# cifar_dataset = CIFAR10PyDataset(train_files, y_labels)\n# print(len(cifar_dataset))\n# x, y = cifar_dataset[0]\n# x.shape, y.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:29.474398Z","iopub.execute_input":"2025-12-16T06:57:29.474752Z","iopub.status.idle":"2025-12-16T06:57:29.498309Z","shell.execute_reply.started":"2025-12-16T06:57:29.474718Z","shell.execute_reply":"2025-12-16T06:57:29.497195Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# x, y = cifar_dataset[1562]\n# x.shape, y.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:29.499471Z","iopub.execute_input":"2025-12-16T06:57:29.499930Z","iopub.status.idle":"2025-12-16T06:57:29.523004Z","shell.execute_reply.started":"2025-12-16T06:57:29.499897Z","shell.execute_reply":"2025-12-16T06:57:29.521763Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_train = y_labels2\ny_cat_train0 = to_categorical(y_labels2)\ny_cat_train = y_cat_train0\nprint(y_cat_train.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:29.524194Z","iopub.execute_input":"2025-12-16T06:57:29.524937Z","iopub.status.idle":"2025-12-16T06:57:29.557372Z","shell.execute_reply.started":"2025-12-16T06:57:29.524898Z","shell.execute_reply":"2025-12-16T06:57:29.556414Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = x_train0[ii*ncols + jj]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:29.558468Z","iopub.execute_input":"2025-12-16T06:57:29.558819Z","iopub.status.idle":"2025-12-16T06:57:41.214967Z","shell.execute_reply.started":"2025-12-16T06:57:29.558778Z","shell.execute_reply":"2025-12-16T06:57:41.213130Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = x_train1[ii*ncols + jj]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:41.216198Z","iopub.execute_input":"2025-12-16T06:57:41.216475Z","iopub.status.idle":"2025-12-16T06:57:54.177564Z","shell.execute_reply.started":"2025-12-16T06:57:41.216456Z","shell.execute_reply":"2025-12-16T06:57:54.176005Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=12\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    idx = (np.array(y_labels) == ii)\n    target_img = x_train0[idx][:ncols]\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = target_img[jj]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:57:54.179435Z","iopub.execute_input":"2025-12-16T06:57:54.179935Z","iopub.status.idle":"2025-12-16T06:58:08.832061Z","shell.execute_reply.started":"2025-12-16T06:57:54.179900Z","shell.execute_reply":"2025-12-16T06:58:08.830733Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = x_test[ii*ncols + jj]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:08.833305Z","iopub.execute_input":"2025-12-16T06:58:08.833738Z","iopub.status.idle":"2025-12-16T06:58:20.220268Z","shell.execute_reply.started":"2025-12-16T06:58:08.833686Z","shell.execute_reply":"2025-12-16T06:58:20.218589Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# from tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n# datagen = ImageDataGenerator(\n#     # set input mean to 0 over the dataset\n#     featurewise_center=False,\n#     # set each sample mean to 0\n#     samplewise_center=False,\n#     # divide inputs by std of dataset\n#     featurewise_std_normalization=False,\n#     # divide each input by its std\n#     samplewise_std_normalization=False,\n#     # apply ZCA whitening\n#     zca_whitening=False,\n#     # epsilon for ZCA whitening\n#     zca_epsilon=1e-06,\n#     # randomly rotate images in the range (deg 0 to 180)\n#     rotation_range=10,\n#     # randomly shift images horizontally\n#     width_shift_range=0.1,\n#     # randomly shift images vertically\n#     height_shift_range=0.1,\n#     # set range for random shear\n#     shear_range=0.,\n#     # set range for random zoom\n#     zoom_range=0.,\n#     # set range for random channel shifts\n#     channel_shift_range=0.,\n#     # set mode for filling points outside the input boundaries\n#     fill_mode='nearest',\n#     # value used for fill_mode = \"constant\"\n#     cval=0.,\n#     # randomly flip images\n#     horizontal_flip=True,\n#     # randomly flip images\n#     vertical_flip=False,\n#     # set rescaling factor (applied before any other transformation)\n#     rescale=None,\n#     # set function that will be applied on each input\n#     preprocessing_function=None,\n#     # image data format, either \"channels_first\" or \"channels_last\"\n#     data_format=None,\n#     # fraction of images reserved for validation (strictly between 0 and 1)\n#     validation_split=0.0)\n\n# datagen.fit(x_train)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.221576Z","iopub.execute_input":"2025-12-16T06:58:20.222005Z","iopub.status.idle":"2025-12-16T06:58:20.228056Z","shell.execute_reply.started":"2025-12-16T06:58:20.221979Z","shell.execute_reply":"2025-12-16T06:58:20.226879Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Conv2DRBF","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.layers import (\n    Input, Conv2D, BatchNormalization, Activation, \n    Add, GlobalAveragePooling2D, GlobalMaxPooling2D, Dense, Reshape, TimeDistributed, Lambda, concatenate\n)\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras import regularizers\nimport tensorflow.keras.backend as K","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.229277Z","iopub.execute_input":"2025-12-16T06:58:20.229602Z","iopub.status.idle":"2025-12-16T06:58:20.253978Z","shell.execute_reply.started":"2025-12-16T06:58:20.229576Z","shell.execute_reply":"2025-12-16T06:58:20.252695Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"THRESHOLD = 0.5\n\ndef f1_score_metric(y_true, y_pred):\n    \"\"\"\n    Kaggleでよく使用されるマクロF1スコアを計算するカスタムメトリック。\n    tf.is_nan を tf.math.is_nan に修正。\n    \"\"\"\n    \n    # y_predを閾値処理してバイナリ化\n    # K.clip(y_pred, 0, 1)は確率値を0〜1にクリップ\n    y_pred_thresh = K.cast(K.greater(K.clip(y_pred, 0, 1), THRESHOLD), K.floatx())\n    \n    # True Positives (TP), False Positives (FP), False Negatives (FN) を計算\n    # 各クラスごと (axis=0 はバッチ、axis=1 はクラス)\n    tp = K.sum(y_true * y_pred_thresh, axis=0)\n    fp = K.sum((1 - y_true) * y_pred_thresh, axis=0)\n    fn = K.sum(y_true * (1 - y_pred_thresh), axis=0)\n\n    # Precision (p) と Recall (r)\n    p = tp / (tp + fp + K.epsilon())\n    r = tp / (tp + fn + K.epsilon())\n\n    # F1 Score (各クラス)\n    f1_per_class = 2 * p * r / (p + r + K.epsilon())\n    \n    # NaNの処理: 0/0 (p=0, r=0の場合)を0に設定\n    # 【修正点】tf.is_nan を tf.math.is_nan に変更\n    f1_per_class = tf.where(tf.math.is_nan(f1_per_class), tf.zeros_like(f1_per_class), f1_per_class)\n    \n    # マクロF1スコア (クラス全体の平均)\n    return K.mean(f1_per_class)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.255130Z","iopub.execute_input":"2025-12-16T06:58:20.255462Z","iopub.status.idle":"2025-12-16T06:58:20.276779Z","shell.execute_reply.started":"2025-12-16T06:58:20.255427Z","shell.execute_reply":"2025-12-16T06:58:20.275708Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.layers import Layer\nfrom tensorflow.keras import initializers, constraints\n\n# class Conv2DRBF(Layer):\n#     \"\"\"\n#     RBFカーネル畳み込みレイヤー (Conv2D-RBF)\n\n#     通常のConv2D層の積和演算（内積）を RBF カーネル（非線形類似度）に置き換えます。\n#     gammaパラメータは log(gamma)として保持され、学習時の安定性を向上させています。\n#     \"\"\"\n#     def __init__(self, filters, kernel_size,\n#                  gamma_initializer=initializers.Constant(np.log(1 / (0.2**2))),\n#                  gamma_regularizer=None,\n#                  kernel_initializer=initializers.RandomUniform(minval=0.0, maxval=1.0),\n#                  strides=(1, 1), padding='valid', **kwargs):\n        \n#         super(Conv2DRBF, self).__init__(**kwargs)\n        \n#         self.filters = filters\n#         self.kernel_size = tuple(kernel_size)\n#         self.strides = tuple(strides)\n#         # tf.image.extract_patchesに対応させるため、paddingを大文字に\n#         self.padding = padding.upper() \n        \n#         # log_gammaのパラメータ設定\n#         # log_gammaの初期値が0の場合、exp(0)=1となり、gamma=1からスタートします。\n#         self.gamma_initializer = initializers.get(gamma_initializer)\n#         self.gamma_regularizer = gamma_regularizer\n#         # log_gammaは非負制約が不要になるため、gamma_constraintは削除しました\n#         self.gamma_constraint = None \n\n#         self.kernel_initializer = kernel_initializer\n\n#     def build(self, input_shape):\n#         # input_shape: (B, H, W, C_in)\n        \n#         input_dim = input_shape[-1]\n        \n#         # 1. ランドマーク (カーネル μ) の定義\n#         # kernel_shape: (kH, kW, C_in, F)\n#         self.kernel = self.add_weight(\n#             shape=self.kernel_size + (input_dim, self.filters),\n#             # 入力がN(0, 1)付近の場合、小さな値 (例: TruncatedNormal) が望ましい\n#             initializer=self.kernel_initializer,\n#             name='rbf_kernel_landmarks',\n#             trainable=True,\n#         )\n\n#         # 2. log_gamma の定義\n#         # gammaの代わりにlog_gammaを学習する。非負制約は不要。\n#         self.log_gamma = self.add_weight(\n#             shape=(1,),\n#             # 初期値が'ones'だとlog_gamma=1となり、gamma=e^1≈2.71からスタート\n#             # 'zeros'だとlog_gamma=0となり、gamma=1からスタート。ここでは'zeros'を推奨\n#             initializer=self.gamma_initializer,\n#             regularizer=self.gamma_regularizer,\n#             name='log_gamma',\n#             trainable=True\n#         )\n        \n#         super(Conv2DRBF, self).build(input_shape)\n\n#     def call(self, inputs):\n#         # inputs: (B, H, W, C_in)\n        \n#         # log_gammaから実際のgamma値を計算\n#         gamma = tf.exp(self.log_gamma)\n\n#         # 1. パッチの抽出 (Sliding Window)\n#         ksizes = [1, self.kernel_size[0], self.kernel_size[1], 1]\n#         strides = [1, self.strides[0], self.strides[1], 1]\n#         rates = [1, 1, 1, 1] \n        \n#         # patches shape: (B, H_out, W_out, kH * kW * C_in)\n#         patches = tf.image.extract_patches(\n#             images=inputs,\n#             sizes=ksizes,\n#             strides=strides,\n#             rates=rates,\n#             padding=self.padding\n#         )\n\n#         # パッチが平坦化された次元サイズ: C_flat\n#         C_flat = tf.shape(patches)[-1]\n#         B, H_out, W_out = tf.shape(patches)[0], tf.shape(patches)[1], tf.shape(patches)[2]\n        \n#         # 2. 距離計算のための形状変更\n        \n#         # パッチ: (B, H_out, W_out, 1, C_flat)\n#         patches_for_dist = tf.reshape(patches, (B, H_out, W_out, 1, C_flat))\n\n#         # ランドマーク: (1, 1, 1, F, C_flat)\n#         kernel_flat = tf.reshape(self.kernel, (1, 1, 1, self.filters, C_flat))\n\n#         # 3. ユークリッド距離の二乗計算: ||x - μ||^2\n#         # (B, H_out, W_out, F, C_flat) から、最後の次元を reduce_sum\n#         sq_dist = tf.reduce_sum(tf.square(patches_for_dist - kernel_flat), axis=-1)\n#         # sq_dist shape: (B, H_out, W_out, F)\n\n#         # 4. RBFカーネル関数の適用: exp(-gamma * ||x - μ||^2)\n#         # tf.exp()を使用してRBFカーネルを計算\n#         rbf_output = tf.exp(-gamma * sq_dist)\n#         # rbf_output shape: (B, H_out, W_out, F)\n\n#         return rbf_output\n\n#     def compute_output_shape(self, input_shape):\n#         # KerasのConv2Dと同様のロジックで出力形状を計算\n#         H_in = input_shape[1]\n#         W_in = input_shape[2]\n        \n#         if self.padding == 'VALID':\n#             H_out = (H_in - self.kernel_size[0]) // self.strides[0] + 1\n#             W_out = (W_in - self.kernel_size[1]) // self.strides[1] + 1\n#         elif self.padding == 'SAME':\n#             H_out = (H_in + self.strides[0] - 1) // self.strides[0]\n#             W_out = (W_in + self.strides[1] - 1) // self.strides[1]\n#         else:\n#             raise ValueError(f\"Unknown padding: {self.padding}\")\n            \n#         return (input_shape[0], H_out, W_out, self.filters)\n\n#     def get_config(self):\n#         # モデル保存・読み込みのためにconfigを定義\n#         config = super(Conv2DRBF, self).get_config()\n#         config.update({\n#             'filters': self.filters,\n#             'kernel_size': self.kernel_size,\n#             'strides': self.strides,\n#             'padding': self.padding.lower(),\n#             'gamma_initializer': initializers.serialize(self.gamma_initializer),\n#             'gamma_regularizer': initializers.serialize(self.gamma_regularizer),\n#             # 'gamma_constraint'はlog_gammaの導入により不要になったため削除\n#         })\n#         return config\n\nclass Conv2DRBF_patch(Layer):\n    \"\"\"\n    RBFカーネル畳み込みレイヤー (Conv2D-RBF)\n\n    通常のConv2D層の積和演算（内積）を RBF カーネル（非線形類似度）に置き換えます。\n    gammaパラメータは log(gamma)として保持され、学習時の安定性を向上させています。\n    \"\"\"\n    def __init__(self, filters, kernel_size,\n                 gamma_initializer=initializers.Constant(np.log(1 / (0.2**2))),\n                 gamma_regularizer=None,\n                 kernel_initializer=initializers.RandomUniform(minval=0.0, maxval=1.0),\n                 strides=(1, 1), padding='valid', **kwargs):\n        \n        super(Conv2DRBF_patch, self).__init__(**kwargs)\n        \n        self.filters = filters\n        self.kernel_size = tuple(kernel_size)\n        self.strides = tuple(strides)\n        # tf.image.extract_patchesに対応させるため、paddingを大文字に\n        self.padding = padding.upper() \n        \n        # log_gammaのパラメータ設定\n        # log_gammaの初期値が0の場合、exp(0)=1となり、gamma=1からスタートします。\n        self.gamma_initializer = initializers.get(gamma_initializer)\n        self.gamma_regularizer = gamma_regularizer\n        # log_gammaは非負制約が不要になるため、gamma_constraintは削除しました\n        self.gamma_constraint = None \n\n        self.kernel_initializer = kernel_initializer\n\n    def build(self, input_shape):\n        # input_shape: (B, H, W, C_in)\n        \n        input_dim = input_shape[-1]\n        \n        # 1. ランドマーク (カーネル μ) の定義\n        # kernel_shape: (kH, kW, C_in, F)\n        self.kernel = self.add_weight(\n            shape=self.kernel_size + (input_dim, self.filters),\n            # 入力がN(0, 1)付近の場合、小さな値 (例: TruncatedNormal) が望ましい\n            initializer=self.kernel_initializer,\n            name='rbf_kernel_landmarks',\n            trainable=True,\n        )\n\n        # 2. log_gamma の定義\n        # gammaの代わりにlog_gammaを学習する。非負制約は不要。\n        self.log_gamma = self.add_weight(\n            shape=(1,),\n            # 初期値が'ones'だとlog_gamma=1となり、gamma=e^1≈2.71からスタート\n            # 'zeros'だとlog_gamma=0となり、gamma=1からスタート。ここでは'zeros'を推奨\n            initializer=self.gamma_initializer,\n            regularizer=self.gamma_regularizer,\n            name='log_gamma',\n            trainable=True\n        )\n        \n        super(Conv2DRBF_patch, self).build(input_shape)\n\n    def call(self, inputs):\n        # inputs: (B, H, W, C_in)\n        \n        # log_gammaから実際のgamma値を計算\n        gamma = tf.exp(self.log_gamma)\n\n        # 1. パッチの抽出 (Sliding Window)\n        ksizes = [1, self.kernel_size[0], self.kernel_size[1], 1]\n        strides = [1, self.strides[0], self.strides[1], 1]\n        rates = [1, 1, 1, 1] \n        \n        # patches shape: (B, H_out, W_out, kH * kW * C_in)\n        patches = tf.image.extract_patches(\n            images=inputs,\n            sizes=ksizes,\n            strides=strides,\n            rates=rates,\n            padding=self.padding\n        )\n\n        # パッチが平坦化された次元サイズ: C_flat\n        C_flat = tf.shape(patches)[-1]\n        B, H_out, W_out = tf.shape(patches)[0], tf.shape(patches)[1], tf.shape(patches)[2]\n        \n        # 2. 距離計算のための形状変更\n        \n        # パッチ: (B, H_out, W_out, 1, C_flat)\n        patches_for_dist = tf.reshape(patches, (B, H_out, W_out, 1, C_flat))\n        return patches_for_dist\n\n        # # ランドマーク: (1, 1, 1, F, C_flat)\n        # kernel_flat = tf.reshape(self.kernel, (1, 1, 1, self.filters, C_flat))\n\n        # # 3. ユークリッド距離の二乗計算: ||x - μ||^2\n        # # (B, H_out, W_out, F, C_flat) から、最後の次元を reduce_sum\n        # sq_dist = tf.reduce_sum(tf.square(patches_for_dist - kernel_flat), axis=-1)\n        # # sq_dist shape: (B, H_out, W_out, F)\n\n        # # 4. RBFカーネル関数の適用: exp(-gamma * ||x - μ||^2)\n        # # tf.exp()を使用してRBFカーネルを計算\n        # rbf_output = tf.exp(-gamma * sq_dist)\n        # rbf_output shape: (B, H_out, W_out, F)\n\n        return rbf_output\n\n    def compute_output_shape(self, input_shape):\n        # KerasのConv2Dと同様のロジックで出力形状を計算\n        H_in = input_shape[1]\n        W_in = input_shape[2]\n        \n        if self.padding == 'VALID':\n            H_out = (H_in - self.kernel_size[0]) // self.strides[0] + 1\n            W_out = (W_in - self.kernel_size[1]) // self.strides[1] + 1\n        elif self.padding == 'SAME':\n            H_out = (H_in + self.strides[0] - 1) // self.strides[0]\n            W_out = (W_in + self.strides[1] - 1) // self.strides[1]\n        else:\n            raise ValueError(f\"Unknown padding: {self.padding}\")\n            \n        return (input_shape[0], H_out, W_out, 1, self.kernel_size[0]*self.kernel_size[1]*input_shape[3])\n\n    def get_config(self):\n        # モデル保存・読み込みのためにconfigを定義\n        config = super(Conv2DRBF_patch, self).get_config()\n        config.update({\n            'filters': self.filters,\n            'kernel_size': self.kernel_size,\n            'strides': self.strides,\n            'padding': self.padding.lower(),\n            'gamma_initializer': initializers.serialize(self.gamma_initializer),\n            'gamma_regularizer': initializers.serialize(self.gamma_regularizer),\n            # 'gamma_constraint'はlog_gammaの導入により不要になったため削除\n        })\n        return config","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.278387Z","iopub.execute_input":"2025-12-16T06:58:20.278779Z","iopub.status.idle":"2025-12-16T06:58:20.313018Z","shell.execute_reply.started":"2025-12-16T06:58:20.278745Z","shell.execute_reply":"2025-12-16T06:58:20.311935Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### rbf_targetをパラメータにするのはやめる\n# class Conv2DRBF(Layer):\n#     \"\"\"\n#     RBFカーネル畳み込みレイヤー (Conv2D-RBF)\n\n#     通常のConv2D層の積和演算（内積）を RBF カーネル（非線形類似度）に置き換えます。\n#     gammaパラメータは log(gamma)として保持され、学習時の安定性を向上させています。\n#     \"\"\"\n#     def __init__(self, filters, kernel_size,\n#                  #gamma_initializer=initializers.Constant(np.log(1 / (0.2**2))),\n#                  gamma_regularizer=None,\n#                  rbf_target=0.01,\n#                  kernel_initializer=initializers.RandomUniform(minval=0.0, maxval=1.0),\n#                  strides=(1, 1), padding='valid', **kwargs):\n        \n#         super(Conv2DRBF, self).__init__(**kwargs)\n        \n#         self.filters = filters\n#         self.kernel_size = tuple(kernel_size)\n#         self.strides = tuple(strides)\n#         # tf.image.extract_patchesに対応させるため、paddingを大文字に\n#         self.padding = padding.upper() \n        \n#         # log_gammaのパラメータ設定\n#         #self.gamma_initializer = initializers.Constant(np.log(1 / (0.2**2)))\n#         self.gamma_regularizer = gamma_regularizer\n#         # log_gammaは非負制約が不要になるため、gamma_constraintは削除しました\n#         self.rbf_target = rbf_target\n\n#         self.kernel_initializer = kernel_initializer\n\n#     def build(self, input_shape):\n#         # input_shape: (B, H, W, C_in)\n        \n#         input_dim = input_shape[-1]\n        \n#         # 1. ランドマーク (カーネル μ) の定義\n#         # kernel_shape: (kH, kW, C_in, F)\n#         self.kernel = self.add_weight(\n#             shape=self.kernel_size + (input_dim, self.filters),\n#             # 入力がN(0, 1)付近の場合、小さな値 (例: TruncatedNormal) が望ましい\n#             initializer=self.kernel_initializer,\n#             name='rbf_kernel_landmarks',\n#             trainable=True,\n#         )\n\n#         # 2. log_gamma の定義\n#         # gammaの代わりにlog_gammaを学習する。非負制約は不要。\n#         D1, D2, Cin = self.kernel_size[0], self.kernel_size[1], input_shape[3]\n#         #print('D1, D2, Cin >>>', D1, D2, Cin)\n#         self.log_gamma = self.add_weight(\n#             shape=(1,),\n#             initializer=initializers.Constant(np.log(-np.log(self.rbf_target) / (D1*D2*Cin))),\n#             regularizer=self.gamma_regularizer,\n#             name='log_gamma',\n#             trainable=True\n#         )\n        \n#         super(Conv2DRBF, self).build(input_shape)\n\n#     def call(self, inputs):\n#         # inputs: (B, H, W, C_in)\n        \n#         # log_gammaから実際のgamma値を計算\n#         gamma = tf.exp(self.log_gamma)\n\n#         # 1. パッチの抽出 (Sliding Window)\n#         ksizes = [1, self.kernel_size[0], self.kernel_size[1], 1]\n#         strides = [1, self.strides[0], self.strides[1], 1]\n#         rates = [1, 1, 1, 1] \n        \n#         # patches shape: (B, H_out, W_out, kH * kW * C_in)\n#         patches = tf.image.extract_patches(\n#             images=inputs,\n#             sizes=ksizes,\n#             strides=strides,\n#             rates=rates,\n#             padding=self.padding\n#         )\n\n#         # パッチが平坦化された次元サイズ: C_flat\n#         C_flat = tf.shape(patches)[-1]\n#         B, H_out, W_out = tf.shape(patches)[0], tf.shape(patches)[1], tf.shape(patches)[2]\n        \n#         # 2. 距離計算のための形状変更\n        \n#         # パッチ: (B, H_out, W_out, 1, C_flat)\n#         patches_for_dist = tf.reshape(patches, (B, H_out, W_out, 1, C_flat))\n\n#         # ランドマーク: (1, 1, 1, F, C_flat)\n#         kernel_flat = tf.reshape(self.kernel, (1, 1, 1, self.filters, C_flat))\n\n#         # 3. ユークリッド距離の二乗計算: ||x - μ||^2\n        \n#         # # (B, H_out, W_out, F, C_flat) から、最後の次元を reduce_sum\n#         # sq_dist = tf.reduce_sum(tf.square(patches_for_dist - kernel_flat), axis=-1)\n#         # # sq_dist shape: (B, H_out, W_out, F)\n        \n#         # パッチのノルム二乗: ||x||^2\n#         # (B, H_out, W_out, 1) - F次元にブロードキャストされる\n#         patch_norm_sq = tf.reduce_sum(tf.square(patches_for_dist), axis=-1)\n#         #print('patch_norm_sq.shape >>>', patch_norm_sq.shape)\n\n#         # ランドマークのノルム二乗: ||μ||^2\n#         # (1, 1, 1, F) - B*H_out*W_out次元にブロードキャストされる\n#         kernel_norm_sq = tf.reduce_sum(tf.square(kernel_flat), axis=-1)\n#         #print('kernel_norm_sq.shape >>>', kernel_norm_sq.shape)\n\n#         # 内積: x・μ\n#         # (B, H_out, W_out, F)\n#         # inner_product = tf.reduce_sum(patches_for_dist * kernel_flat, axis=-1)\n#         inner_product = tf.tensordot(tf.reshape(patches, (B, H_out, W_out, C_flat)), tf.reshape(self.kernel, (self.filters, C_flat)), axes=[[3], [1]])\n#         #print('inner_product.shape >>>', inner_product.shape)\n        \n#         # 組み合わせ: ||x||^2 + ||μ||^2 - 2(x・μ)\n#         sq_dist = patch_norm_sq + kernel_norm_sq - 2.0 * inner_product\n#         # sq_dist shape: (B, H_out, W_out, F)\n\n#         # 4. RBFカーネル関数の適用: exp(-gamma * ||x - μ||^2)\n#         # tf.exp()を使用してRBFカーネルを計算\n#         rbf_output = tf.exp(-gamma * sq_dist)\n#         # rbf_output shape: (B, H_out, W_out, F)\n\n#         return rbf_output\n\n#     def compute_output_shape(self, input_shape):\n#         # KerasのConv2Dと同様のロジックで出力形状を計算\n#         H_in = input_shape[1]\n#         W_in = input_shape[2]\n        \n#         if self.padding == 'VALID':\n#             H_out = (H_in - self.kernel_size[0]) // self.strides[0] + 1\n#             W_out = (W_in - self.kernel_size[1]) // self.strides[1] + 1\n#         elif self.padding == 'SAME':\n#             H_out = (H_in + self.strides[0] - 1) // self.strides[0]\n#             W_out = (W_in + self.strides[1] - 1) // self.strides[1]\n#         else:\n#             raise ValueError(f\"Unknown padding: {self.padding}\")\n            \n#         return (input_shape[0], H_out, W_out, self.filters)\n\n#     def get_config(self):\n#         # モデル保存・読み込みのためにconfigを定義\n#         config = super(Conv2DRBF, self).get_config()\n#         config.update({\n#             'filters': self.filters,\n#             'kernel_size': self.kernel_size,\n#             'strides': self.strides,\n#             'padding': self.padding.lower(),\n#             'gamma_initializer': initializers.serialize(self.gamma_initializer),\n#             'gamma_regularizer': initializers.serialize(self.gamma_regularizer),\n#             # 'gamma_constraint'はlog_gammaの導入により不要になったため削除\n#         })\n#         return config\n\nclass Conv2DRBF(Layer):\n    \"\"\"\n    RBFカーネル畳み込みレイヤー (Conv2D-RBF)\n\n    通常のConv2D層の積和演算（内積）を RBF カーネル（非線形類似度）に置き換えます。\n    gammaパラメータは log(gamma)として保持され、学習時の安定性を向上させています。\n    \"\"\"\n    def __init__(self, filters, kernel_size,\n                 gamma_initializer=initializers.Constant(np.log(1 / (0.2**2))),\n                 gamma_regularizer=None,\n                 kernel_initializer=initializers.RandomUniform(minval=0.0, maxval=1.0),\n                 strides=(1, 1), padding='valid', **kwargs):\n        \n        super(Conv2DRBF, self).__init__(**kwargs)\n        \n        self.filters = filters\n        self.kernel_size = tuple(kernel_size)\n        self.strides = tuple(strides)\n        # tf.image.extract_patchesに対応させるため、paddingを大文字に\n        self.padding = padding.upper() \n        \n        # log_gammaのパラメータ設定\n        # log_gammaの初期値が0の場合、exp(0)=1となり、gamma=1からスタートします。\n        self.gamma_initializer = initializers.get(gamma_initializer)\n        self.gamma_regularizer = gamma_regularizer\n        # log_gammaは非負制約が不要になるため、gamma_constraintは削除しました\n        self.gamma_constraint = None \n\n        self.kernel_initializer = kernel_initializer\n\n    def build(self, input_shape):\n        # input_shape: (B, H, W, C_in)\n        \n        input_dim = input_shape[-1]\n        \n        # 1. ランドマーク (カーネル μ) の定義\n        # kernel_shape: (kH, kW, C_in, F)\n        self.kernel = self.add_weight(\n            shape=self.kernel_size + (input_dim, self.filters),\n            # 入力がN(0, 1)付近の場合、小さな値 (例: TruncatedNormal) が望ましい\n            initializer=self.kernel_initializer,\n            name='rbf_kernel_landmarks',\n            trainable=True,\n        )\n\n        # 2. log_gamma の定義\n        # gammaの代わりにlog_gammaを学習する。非負制約は不要。\n        self.log_gamma = self.add_weight(\n            shape=(1,),\n            # 初期値が'ones'だとlog_gamma=1となり、gamma=e^1≈2.71からスタート\n            # 'zeros'だとlog_gamma=0となり、gamma=1からスタート。ここでは'zeros'を推奨\n            initializer=self.gamma_initializer,\n            regularizer=self.gamma_regularizer,\n            name='log_gamma',\n            trainable=True\n        )\n        \n        super(Conv2DRBF, self).build(input_shape)\n\n    def call(self, inputs):\n        # inputs: (B, H, W, C_in)\n        \n        # log_gammaから実際のgamma値を計算\n        gamma = tf.exp(self.log_gamma)\n\n        # 1. パッチの抽出 (Sliding Window)\n        ksizes = [1, self.kernel_size[0], self.kernel_size[1], 1]\n        strides = [1, self.strides[0], self.strides[1], 1]\n        rates = [1, 1, 1, 1] \n        \n        # patches shape: (B, H_out, W_out, kH * kW * C_in)\n        patches = tf.image.extract_patches(\n            images=inputs,\n            sizes=ksizes,\n            strides=strides,\n            rates=rates,\n            padding=self.padding\n        )\n\n        # パッチが平坦化された次元サイズ: C_flat\n        C_flat = tf.shape(patches)[-1]\n        B, H_out, W_out = tf.shape(patches)[0], tf.shape(patches)[1], tf.shape(patches)[2]\n        \n        # 2. 距離計算のための形状変更\n        \n        # パッチ: (B, H_out, W_out, 1, C_flat)\n        patches_for_dist = tf.reshape(patches, (B, H_out, W_out, 1, C_flat))\n\n        # ランドマーク: (1, 1, 1, F, C_flat)\n        kernel_flat = tf.reshape(self.kernel, (1, 1, 1, self.filters, C_flat))\n\n        # 3. ユークリッド距離の二乗計算: ||x - μ||^2\n        \n        # # (B, H_out, W_out, F, C_flat) から、最後の次元を reduce_sum\n        # sq_dist = tf.reduce_sum(tf.square(patches_for_dist - kernel_flat), axis=-1)\n        # # sq_dist shape: (B, H_out, W_out, F)\n        \n        # パッチのノルム二乗: ||x||^2\n        # (B, H_out, W_out, 1) - F次元にブロードキャストされる\n        patch_norm_sq = tf.reduce_sum(tf.square(patches_for_dist), axis=-1)\n        #print('patch_norm_sq.shape >>>', patch_norm_sq.shape)\n\n        # ランドマークのノルム二乗: ||μ||^2\n        # (1, 1, 1, F) - B*H_out*W_out次元にブロードキャストされる\n        kernel_norm_sq = tf.reduce_sum(tf.square(kernel_flat), axis=-1)\n        #print('kernel_norm_sq.shape >>>', kernel_norm_sq.shape)\n\n        # 内積: x・μ\n        # (B, H_out, W_out, F)\n        # inner_product = tf.reduce_sum(patches_for_dist * kernel_flat, axis=-1)\n        inner_product = tf.tensordot(tf.reshape(patches, (B, H_out, W_out, C_flat)), tf.reshape(self.kernel, (self.filters, C_flat)), axes=[[3], [1]])\n        #print('inner_product.shape >>>', inner_product.shape)\n        \n        # 組み合わせ: ||x||^2 + ||μ||^2 - 2(x・μ)\n        sq_dist = patch_norm_sq + kernel_norm_sq - 2.0 * inner_product\n        # sq_dist shape: (B, H_out, W_out, F)\n\n        # 4. RBFカーネル関数の適用: exp(-gamma * ||x - μ||^2)\n        # tf.exp()を使用してRBFカーネルを計算\n        rbf_output = tf.exp(-gamma * sq_dist)\n        # rbf_output shape: (B, H_out, W_out, F)\n\n        return rbf_output\n\n    def compute_output_shape(self, input_shape):\n        # KerasのConv2Dと同様のロジックで出力形状を計算\n        H_in = input_shape[1]\n        W_in = input_shape[2]\n        \n        if self.padding == 'VALID':\n            H_out = (H_in - self.kernel_size[0]) // self.strides[0] + 1\n            W_out = (W_in - self.kernel_size[1]) // self.strides[1] + 1\n        elif self.padding == 'SAME':\n            H_out = (H_in + self.strides[0] - 1) // self.strides[0]\n            W_out = (W_in + self.strides[1] - 1) // self.strides[1]\n        else:\n            raise ValueError(f\"Unknown padding: {self.padding}\")\n            \n        return (input_shape[0], H_out, W_out, self.filters)\n\n    def get_config(self):\n        # モデル保存・読み込みのためにconfigを定義\n        config = super(Conv2DRBF, self).get_config()\n        config.update({\n            'filters': self.filters,\n            'kernel_size': self.kernel_size,\n            'strides': self.strides,\n            'padding': self.padding.lower(),\n            'gamma_initializer': initializers.serialize(self.gamma_initializer),\n            'gamma_regularizer': initializers.serialize(self.gamma_regularizer),\n            # 'gamma_constraint'はlog_gammaの導入により不要になったため削除\n        })\n        return config","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.314384Z","iopub.execute_input":"2025-12-16T06:58:20.314896Z","iopub.status.idle":"2025-12-16T06:58:20.353561Z","shell.execute_reply.started":"2025-12-16T06:58:20.314781Z","shell.execute_reply":"2025-12-16T06:58:20.352466Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"inputs = Input(shape=(32, 32, 3))\nx = Conv2DRBF_patch(\n            filters=16, \n            kernel_size=(3, 3), \n            strides=(1, 1), \n            padding='same',\n            kernel_initializer=initializers.RandomUniform(minval=0.4, maxval=0.6, seed=10001),\n            name='rbf_conv_patch'\n        )(inputs)\nmodel_test = Model(inputs=inputs, outputs=x, name=f'Conv2DRBF_patch')\nmodel_test.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\nmodel_test.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.355277Z","iopub.execute_input":"2025-12-16T06:58:20.355601Z","iopub.status.idle":"2025-12-16T06:58:20.506112Z","shell.execute_reply.started":"2025-12-16T06:58:20.355565Z","shell.execute_reply":"2025-12-16T06:58:20.504910Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ロジック②のための出力確定用\ninputs = Input(shape=(32, 32, 3))\nx = Conv2DRBF(\n            filters=16,\n            #rbf_target=0.1,\n            kernel_size=(3, 3), \n            strides=(1, 1), \n            padding='same',\n            kernel_initializer=initializers.RandomUniform(minval=0.4, maxval=0.6, seed=10001),\n            name='rbf_conv'\n        )(inputs)\nmodel_test = Model(inputs=inputs, outputs=x, name=f'Conv2DRBF_patch')\nmodel_test.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\nmodel_test.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.507208Z","iopub.execute_input":"2025-12-16T06:58:20.507536Z","iopub.status.idle":"2025-12-16T06:58:20.545024Z","shell.execute_reply.started":"2025-12-16T06:58:20.507492Z","shell.execute_reply":"2025-12-16T06:58:20.543944Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"rbf_conv = model_test.get_layer('rbf_conv')\nrbf_conv.get_weights()[1], np.log(-np.log(0.1)/(3*3*3)), np.exp(rbf_conv.get_weights()[1]), -np.log(0.1)/(3*3*3), ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.546170Z","iopub.execute_input":"2025-12-16T06:58:20.546850Z","iopub.status.idle":"2025-12-16T06:58:20.560038Z","shell.execute_reply.started":"2025-12-16T06:58:20.546823Z","shell.execute_reply":"2025-12-16T06:58:20.558987Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ロジック②のための出力確定用\ninputs = Input(shape=(32, 32, 3))\nx = Conv2DRBF(\n            filters=16, \n            kernel_size=(3, 3), \n            strides=(1, 1), \n            padding='same',\n            kernel_initializer=initializers.RandomUniform(minval=0.4, maxval=0.6, seed=10001),\n            name='rbf_conv'\n        )(inputs)\nmodel_test = Model(inputs=inputs, outputs=x, name=f'Conv2DRBF_patch')\nmodel_test.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\nmodel_test.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.561120Z","iopub.execute_input":"2025-12-16T06:58:20.561454Z","iopub.status.idle":"2025-12-16T06:58:20.597068Z","shell.execute_reply.started":"2025-12-16T06:58:20.561425Z","shell.execute_reply":"2025-12-16T06:58:20.595751Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"rbf_conv = model_test.get_layer('rbf_conv')\nrbf_conv.get_weights()[1], np.log(-np.log(0.01)/(3*3*3)), np.exp(rbf_conv.get_weights()[1]), -np.log(0.01)/(3*3*3)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.598423Z","iopub.execute_input":"2025-12-16T06:58:20.598897Z","iopub.status.idle":"2025-12-16T06:58:20.612047Z","shell.execute_reply.started":"2025-12-16T06:58:20.598868Z","shell.execute_reply":"2025-12-16T06:58:20.609964Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred_tmp = model_test.predict(x_train[:5])\npred_tmp.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.613540Z","iopub.execute_input":"2025-12-16T06:58:20.614661Z","iopub.status.idle":"2025-12-16T06:58:20.850636Z","shell.execute_reply.started":"2025-12-16T06:58:20.614623Z","shell.execute_reply":"2025-12-16T06:58:20.849065Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred_tmp[0,:,:,0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.852024Z","iopub.execute_input":"2025-12-16T06:58:20.852368Z","iopub.status.idle":"2025-12-16T06:58:20.860890Z","shell.execute_reply.started":"2025-12-16T06:58:20.852337Z","shell.execute_reply":"2025-12-16T06:58:20.859823Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"```\narray([[0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ..., 2.1169656e-32,\n        1.5532900e-32, 0.0000000e+00],\n       [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ..., 6.0265011e-09,\n        4.5376872e-10, 1.8092175e-32],\n       [0.0000000e+00, 0.0000000e+00, 0.0000000e+00, ..., 1.6769408e-12,\n        1.2224111e-14, 5.3832547e-36],\n       ...,\n       [2.2700840e-37, 1.6354445e-19, 3.0376850e-22, ..., 2.9154076e-18,\n        2.7575650e-28, 0.0000000e+00],\n       [9.9139967e-33, 6.3302748e-13, 1.1412688e-16, ..., 6.3013600e-14,\n        2.1247140e-19, 0.0000000e+00],\n       [0.0000000e+00, 1.9726915e-35, 7.7242789e-38, ..., 8.0902561e-37,\n        0.0000000e+00, 0.0000000e+00]], dtype=float32)\n```","metadata":{}},{"cell_type":"code","source":"pred_tmp[4,:,:,0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.862230Z","iopub.execute_input":"2025-12-16T06:58:20.862586Z","iopub.status.idle":"2025-12-16T06:58:20.883634Z","shell.execute_reply.started":"2025-12-16T06:58:20.862559Z","shell.execute_reply":"2025-12-16T06:58:20.882393Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"```\narray([[0.0000000e+00, 1.1824578e-37, 1.8343552e-38, ..., 0.0000000e+00,\n        2.7678475e-38, 0.0000000e+00],\n       [7.8956813e-35, 5.0660190e-14, 2.8089554e-14, ..., 8.4325042e-18,\n        3.9024241e-17, 3.4462602e-37],\n       [5.1693958e-33, 8.0586371e-11, 4.3569481e-10, ..., 1.7561913e-17,\n        1.0253279e-16, 7.8984446e-37],\n       ...,\n       [1.7020793e-34, 2.9708755e-13, 9.4201437e-13, ..., 1.5256531e-26,\n        3.0561479e-26, 0.0000000e+00],\n       [4.7863794e-35, 3.5058839e-14, 9.8011504e-14, ..., 8.4140086e-15,\n        3.6790910e-15, 2.4343777e-36],\n       [0.0000000e+00, 2.2774566e-37, 5.4866427e-37, ..., 9.0726923e-37,\n        8.9263788e-37, 0.0000000e+00]], dtype=float32)\n```","metadata":{}},{"cell_type":"code","source":"# # ----------------------------------------------------------------------\n# # 使用例\n# # ----------------------------------------------------------------------\n\n# # 議論に基づいたハイブリッドモデル構築例\n# def create_hybrid_model(input_shape=(32, 32, 3), num_classes=10):\n#     model = tf.keras.models.Sequential([\n#         # 1. 初段にConv2D-RBFを配置 (安定性が高く、計算コストも低い)\n#         Conv2DRBF(\n#             filters=16, \n#             kernel_size=(3, 3), \n#             strides=(1, 1), \n#             padding='same', \n#             name='rbf_conv_feature_extract'\n#         ),\n#         # RBFの出力は0-1なので、ReLUなどの活性化関数は不要\n        \n#         tf.keras.layers.MaxPooling2D((2, 2)), # 16x16x16\n        \n#         # 2. 後続は計算効率の良い標準Conv2Dで特徴を集約・抽象化\n#         tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same', name='conv2d_2'),\n#         tf.keras.layers.MaxPooling2D((2, 2)), # 8x8x32\n        \n#         tf.keras.layers.Flatten(),\n#         tf.keras.layers.Dense(128, activation='relu'),\n#         tf.keras.layers.Dense(num_classes, activation='softmax')\n#     ])\n#     return model\n\n# # モデルの確認\n# hybrid_model = create_hybrid_model()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.884970Z","iopub.execute_input":"2025-12-16T06:58:20.885297Z","iopub.status.idle":"2025-12-16T06:58:20.904818Z","shell.execute_reply.started":"2025-12-16T06:58:20.885272Z","shell.execute_reply":"2025-12-16T06:58:20.903375Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 議論に基づいたハイブリッドモデル構築例\ndef create_hybrid_model(input_shape=(32, 32, 3), num_classes=10):\n    inputs = Input(shape=input_shape)\n    x = Conv2DRBF(\n            filters=16, \n            kernel_size=(3, 3), \n            strides=(1, 1), \n            padding='same',\n            kernel_initializer=initializers.RandomUniform(minval=0.4, maxval=0.6),\n            name='rbf_conv_feature_extract'\n        )(inputs)\n    x = tf.keras.layers.MaxPooling2D((2, 2))(x)\n\n    # 2. 後続は計算効率の良い標準Conv2Dで特徴を集約・抽象化\n    x = tf.keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same', name='conv2d_2')(x)\n    x = tf.keras.layers.MaxPooling2D((2, 2))(x)\n\n    x = tf.keras.layers.Flatten()(x)\n    x = tf.keras.layers.Dense(128, activation='relu')(x)\n    x = tf.keras.layers.Dense(num_classes, activation='softmax')(x)\n    model = Model(inputs=inputs, outputs=x, name=f'Conv2DRBF_hybrid')\n    return model\n\n# モデルの確認\nhybrid_model = create_hybrid_model()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.905941Z","iopub.execute_input":"2025-12-16T06:58:20.906462Z","iopub.status.idle":"2025-12-16T06:58:20.983104Z","shell.execute_reply.started":"2025-12-16T06:58:20.906421Z","shell.execute_reply":"2025-12-16T06:58:20.982098Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"hybrid_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\nhybrid_model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:20.984367Z","iopub.execute_input":"2025-12-16T06:58:20.984807Z","iopub.status.idle":"2025-12-16T06:58:21.015049Z","shell.execute_reply.started":"2025-12-16T06:58:20.984757Z","shell.execute_reply":"2025-12-16T06:58:21.013628Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_model(hybrid_model, show_shapes=True, expand_nested=True, show_layer_names=True, dpi=70)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.015951Z","iopub.execute_input":"2025-12-16T06:58:21.016268Z","iopub.status.idle":"2025-12-16T06:58:21.392956Z","shell.execute_reply.started":"2025-12-16T06:58:21.016246Z","shell.execute_reply":"2025-12-16T06:58:21.390249Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred = hybrid_model.predict(x_train[:5])\npred.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.394601Z","iopub.execute_input":"2025-12-16T06:58:21.394988Z","iopub.status.idle":"2025-12-16T06:58:21.620011Z","shell.execute_reply.started":"2025-12-16T06:58:21.394953Z","shell.execute_reply":"2025-12-16T06:58:21.619010Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.621148Z","iopub.execute_input":"2025-12-16T06:58:21.621525Z","iopub.status.idle":"2025-12-16T06:58:21.629196Z","shell.execute_reply.started":"2025-12-16T06:58:21.621492Z","shell.execute_reply":"2025-12-16T06:58:21.628075Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"hybrid_model.layers","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.630279Z","iopub.execute_input":"2025-12-16T06:58:21.630548Z","iopub.status.idle":"2025-12-16T06:58:21.650754Z","shell.execute_reply.started":"2025-12-16T06:58:21.630524Z","shell.execute_reply":"2025-12-16T06:58:21.649592Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"hybrid_model.layers[1].output","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.651789Z","iopub.execute_input":"2025-12-16T06:58:21.652254Z","iopub.status.idle":"2025-12-16T06:58:21.679949Z","shell.execute_reply.started":"2025-12-16T06:58:21.652229Z","shell.execute_reply":"2025-12-16T06:58:21.678756Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_test = Model(inputs=hybrid_model.input, outputs=hybrid_model.layers[1].output)\nmodel_test.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.681138Z","iopub.execute_input":"2025-12-16T06:58:21.681421Z","iopub.status.idle":"2025-12-16T06:58:21.725778Z","shell.execute_reply.started":"2025-12-16T06:58:21.681392Z","shell.execute_reply":"2025-12-16T06:58:21.724514Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_model(model_test, show_shapes=True, expand_nested=True, show_layer_names=True, dpi=70)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.727148Z","iopub.execute_input":"2025-12-16T06:58:21.727468Z","iopub.status.idle":"2025-12-16T06:58:21.789713Z","shell.execute_reply.started":"2025-12-16T06:58:21.727441Z","shell.execute_reply":"2025-12-16T06:58:21.788717Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"rbf_conv_feature_extract = hybrid_model.get_layer('rbf_conv_feature_extract')\nrbf_conv_feature_extract","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.790860Z","iopub.execute_input":"2025-12-16T06:58:21.791284Z","iopub.status.idle":"2025-12-16T06:58:21.798043Z","shell.execute_reply.started":"2025-12-16T06:58:21.791251Z","shell.execute_reply":"2025-12-16T06:58:21.796985Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for ee in rbf_conv_feature_extract.weights:\n    print(ee.name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.799308Z","iopub.execute_input":"2025-12-16T06:58:21.799976Z","iopub.status.idle":"2025-12-16T06:58:21.818138Z","shell.execute_reply.started":"2025-12-16T06:58:21.799939Z","shell.execute_reply":"2025-12-16T06:58:21.817051Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"log_gamma = rbf_conv_feature_extract.get_weights()[1]\nnp.exp(log_gamma)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.819406Z","iopub.execute_input":"2025-12-16T06:58:21.819776Z","iopub.status.idle":"2025-12-16T06:58:21.843033Z","shell.execute_reply.started":"2025-12-16T06:58:21.819745Z","shell.execute_reply":"2025-12-16T06:58:21.841745Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"filters = rbf_conv_feature_extract.get_weights()[0]\nfilters.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.844262Z","iopub.execute_input":"2025-12-16T06:58:21.844895Z","iopub.status.idle":"2025-12-16T06:58:21.863321Z","shell.execute_reply.started":"2025-12-16T06:58:21.844856Z","shell.execute_reply":"2025-12-16T06:58:21.862258Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"filters.reshape(-1, filters.shape[-1]).shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.864499Z","iopub.execute_input":"2025-12-16T06:58:21.864938Z","iopub.status.idle":"2025-12-16T06:58:21.886968Z","shell.execute_reply.started":"2025-12-16T06:58:21.864907Z","shell.execute_reply":"2025-12-16T06:58:21.885974Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_tmp = pd.DataFrame(filters.reshape(-1, filters.shape[-1])[:,:3])\ndf_tmp.columns = [\"col1\", \"col2\", \"col3\"]\n# # df['cls'] = [str(ee) for ee in y] + ['Landmark']*wgt.shape[0]\n# # sns.lmplot(data=df, x=\"col1\", y=\"col2\", markers=['.', '.', 'o'], hue=\"cls\", fit_reg=False, height=6)\nsns.set_context('paper')\ng = sns.PairGrid(df_tmp, height=2.5)\ng.map_diag(plt.hist, edgecolor=\"w\")\ng.map_lower(scatter)\ng.map_upper(hexbin)\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:21.888091Z","iopub.execute_input":"2025-12-16T06:58:21.888366Z","iopub.status.idle":"2025-12-16T06:58:25.652263Z","shell.execute_reply.started":"2025-12-16T06:58:21.888342Z","shell.execute_reply":"2025-12-16T06:58:25.651021Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"df_tmp = pd.DataFrame(filters.reshape(-1, filters.shape[-1])[:,13:16])\ndf_tmp.columns = [\"col1\", \"col2\", \"col3\"]\n# # df['cls'] = [str(ee) for ee in y] + ['Landmark']*wgt.shape[0]\n# # sns.lmplot(data=df, x=\"col1\", y=\"col2\", markers=['.', '.', 'o'], hue=\"cls\", fit_reg=False, height=6)\nsns.set_context('paper')\ng = sns.PairGrid(df_tmp, height=2.5)\ng.map_diag(plt.hist, edgecolor=\"w\")\ng.map_lower(scatter)\ng.map_upper(hexbin)\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:25.653288Z","iopub.execute_input":"2025-12-16T06:58:25.653564Z","iopub.status.idle":"2025-12-16T06:58:28.494212Z","shell.execute_reply.started":"2025-12-16T06:58:25.653539Z","shell.execute_reply":"2025-12-16T06:58:28.492734Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# ResNet","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.layers import (\n    Input, Conv2D, BatchNormalization, Activation, \n    Add, GlobalAveragePooling2D, GlobalMaxPooling2D, Dense, Reshape, TimeDistributed, Lambda, concatenate\n)\nfrom tensorflow.keras.models import Model\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras import regularizers\nimport tensorflow.keras.backend as K","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:28.495204Z","iopub.execute_input":"2025-12-16T06:58:28.495515Z","iopub.status.idle":"2025-12-16T06:58:28.502199Z","shell.execute_reply.started":"2025-12-16T06:58:28.495485Z","shell.execute_reply":"2025-12-16T06:58:28.500931Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Hybrid_resnet_layer","metadata":{}},{"cell_type":"code","source":"# rl = 0.008\nrl = 0.005\n# rl = 0.01\n# rl = 0.02\nrbf_target = 0.1\n# num_epoch = 16\nnum_epoch = 256\nstructure = 'S2B4'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:28.503191Z","iopub.execute_input":"2025-12-16T06:58:28.503533Z","iopub.status.idle":"2025-12-16T06:58:28.520610Z","shell.execute_reply.started":"2025-12-16T06:58:28.503498Z","shell.execute_reply":"2025-12-16T06:58:28.519516Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def Hybrid_resnet_layer(inputs,\n                      num_filters=16,\n                      kernel_size=3,\n                      strides=1,\n                      activation=None, # 'rbf'が指定されたらC-RBFに置き換え\n                      batch_normalization=False,\n                      conv_first=True,\n                      stage=None, res_block=None, unit=None):\n    \n    Cin = inputs.shape[-1]\n    # conv = Conv2D(num_filters,\n    #               kernel_size=kernel_size,\n    #               strides=strides,\n    #               padding='same',\n    #               kernel_initializer='he_normal',\n    #               kernel_regularizer=regularizers.l2(1e-4),\n    #               name=f'conv2d_{stage}_{res_block}_{unit}')\n    conv = Conv2DRBF(\n            filters=num_filters,\n            kernel_size=(kernel_size, kernel_size),\n            strides=(strides, strides), \n            padding='same', \n            # gamma_initializer=initializers.Constant(np.log(1 / (0.2**2))),\n            # gamma_initializer=initializers.Constant(np.log(-np.log(0.001) / 3)),\n            # gamma_initializer=initializers.Constant(np.log(-np.log(0.5) / 3)),\n            gamma_initializer=initializers.Constant(np.log(-np.log(rbf_target) / (kernel_size**2 * Cin))),\n            # rbf_target = 0.1,\n            kernel_initializer=initializers.RandomUniform(minval=0.4, maxval=0.6),\n            name=f'rbf_conv2d_{stage}_{res_block}_{unit}'\n        )\n    x = inputs\n    if conv_first:\n        # Conv-BN-Activation (ResNet V1 style: RBFは通常、Add()の前に入れる)\n        x = conv(x)\n        # RBF出力なのでBNもReLUも不要\n        # if batch_normalization:\n        #     x = BatchNormalization(name=f'bn_{stage}_{res_block}_{unit}')(x)\n        # if activation is not None:\n        #     x = Activation(activation, name=f'act_{stage}_{res_block}_{unit}')(x)\n    else:\n        # BN-Activation-Conv (ResNet V2 style: RBFはBNの後、Convの前に来る)\n        # if batch_normalization:\n        #     x = BatchNormalization(name=f'bn_{stage}_{res_block}_{unit}')(x)\n\n        # === 🎯 ここが 'relu' の置き換えポイント ===\n        if activation == 'rbf':\n            # 出力チャンネル数（ここでは入力チャンネル数）を使用\n            current_filters = K.int_shape(x)[-1] \n            #x = C_RBF_Transform_Block(x, name=f'rbf_act_{current_filters}', stage=stage, res_block=res_block, unit=unit)\n            x = CRBFActivation(name=f'rbf_act_{stage}_{res_block}_{unit}', num_landmarks=current_filters)(x)\n        elif activation is not None:\n            x = Activation(activation, name=f'act_{stage}_{res_block}_{unit}')(x)\n        \n        x = conv(x)\n    return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:28.521638Z","iopub.execute_input":"2025-12-16T06:58:28.521973Z","iopub.status.idle":"2025-12-16T06:58:28.542997Z","shell.execute_reply.started":"2025-12-16T06:58:28.521942Z","shell.execute_reply":"2025-12-16T06:58:28.541753Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Hybrid_resnet_layer test\ninp = Input(shape=(8, 8, 32))\noup = Hybrid_resnet_layer(inp, num_filters=64)\nmodel_tmp = Model(inp, oup, name='tmp_m')\nmodel_tmp.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])\nmodel_tmp.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:28.544432Z","iopub.execute_input":"2025-12-16T06:58:28.545366Z","iopub.status.idle":"2025-12-16T06:58:28.601756Z","shell.execute_reply.started":"2025-12-16T06:58:28.545334Z","shell.execute_reply":"2025-12-16T06:58:28.600961Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_model(model_tmp, show_shapes=True, expand_nested=True, show_layer_names=True, dpi=70)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:28.602890Z","iopub.execute_input":"2025-12-16T06:58:28.603238Z","iopub.status.idle":"2025-12-16T06:58:28.657404Z","shell.execute_reply.started":"2025-12-16T06:58:28.603208Z","shell.execute_reply":"2025-12-16T06:58:28.656341Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## ResNet20_C_RBF_Hybrid","metadata":{}},{"cell_type":"code","source":"def ResNet20_C_RBF_Hybrid(input_shape=(28, 28, 1), num_stages=3, depth=20, num_classes=10, activation='relu'):\n    \"\"\"\n    ResNet Version 2 (Bottleneck Block) Model builder。\n    RBF活性化をBottleneck Blockの2nd層(3x3 Convの前)に限定します。\n    \"\"\"\n    if (depth - 2) % 9 != 0:\n        raise ValueError('depth should be 9n+2 (eg 20, 38, 56, 110)')\n        \n    num_filters_in = 16\n    num_res_blocks = int((depth - 2) / 9)\n\n    inputs = Input(shape=input_shape, name='input')\n    # Initial Conv (v2 performs Conv2D with BN-ReLU on input)\n    # Stage 0の最初の層はBN-ReLU-Convの構造が特殊なので、そのままReLUを使用\n    x = Hybrid_resnet_layer(inputs=inputs,\n                            num_filters=num_filters_in,\n                            conv_first=True,\n                            activation=None, # 初期層はReLU固定\n                            stage=0, res_block=0, unit='init') # ここはConv-BN-ReLU\n\n    # Instantiate the stack of residual units\n    for stage in range(num_stages):\n        print(f'STAGE START : {stage+1} >>>', x.shape)\n        for res_block in range(num_res_blocks):\n            # --- Bottleneck Blockの特殊処理のための変数設定 ---\n            block_activation = activation \n            batch_normalization = True\n            strides = 1\n            \n            if stage == 0:\n                num_filters_out = num_filters_in * 4\n                if res_block == 0:  # first layer and first stage\n                    # 論文の構造では、最初のブロックのショートカットは非活性化\n                    block_activation = None  \n                    batch_normalization = False\n            else:\n                num_filters_out = num_filters_in * 2\n                if res_block == 0:  # first layer but not first stage\n                    strides = 2   # downsample\n\n            # Bottleneck Residual Unit (3 Conv Layers) - BN-RBF-Conv\n            \n            # 1st: 1x1 Conv (活性化を ReLU に固定。ただし、Noneの場合は維持)\n            # block_activation が None (ダウンサンプルの最初) の場合を除き、強制的に 'relu' に\n            activation_1st = 'relu' if block_activation == 'rbf' else block_activation \n\n            print('BLOCK START : x.shape >>>', x.shape)\n            y = Hybrid_resnet_layer(inputs=x,\n                                    num_filters=num_filters_in,\n                                    kernel_size=1,\n                                    strides=strides,\n                                    activation=None, # relu or None\n                                    batch_normalization=None,\n                                    conv_first=False,\n                                    stage=stage+1, res_block=res_block+1, unit='1st')\n            \n            # 2nd: 3x3 Conv\n            y = Hybrid_resnet_layer(inputs=y,\n                                    num_filters=num_filters_in,\n                                    activation=None,\n                                    conv_first=False,\n                                    stage=stage+1, res_block=res_block+1, unit='2nd')\n            print(f'y.shape stage={stage+1} res_block={res_block+1} unit={\"2nd\"} >>> ', y.shape)\n            \n            # 3rd: 1x1 Conv (活性化を ReLU に固定)\n            y = Hybrid_resnet_layer(inputs=y,\n                                    num_filters=num_filters_out,\n                                    kernel_size=1,\n                                    activation=None,\n                                    conv_first=False,\n                                    stage=stage+1, res_block=res_block+1, unit='3rd')\n            print(f'y.shape stage={stage+1} res_block={res_block+1} unit={\"2nd\"} >>> ', y.shape)\n            \n            # Shortcut Path\n            if res_block == 0:\n                # linear projection residual shortcut connection\n                x = Hybrid_resnet_layer(inputs=x,\n                                        num_filters=num_filters_out,\n                                        kernel_size=1,\n                                        strides=strides,\n                                        activation=None, # Shortcutは活性化なし\n                                        batch_normalization=False,\n                                        stage=stage+1, res_block=res_block+1, unit='sc')\n                print(f'x_sc.shape stage={stage+1} res_block={res_block+1} unit={\"sc\"} >>> ', x.shape)\n\n            x = Add(name=f'res_add_{stage+1}_{res_block+1}')([x, y]) # Addの後に活性化関数はない (V2の特徴)\n\n        num_filters_in = num_filters_out\n\n    # Add classifier on top.\n    # Final Stage (V2 final BN-ReLU before Pooling)\n    #x = BatchNormalization(name='final_bn')(x) # V2 final BN\n    #x = Activation('relu', name='final_relu')(x)   # V2 final ReLU\n    \n    # 分類ヘッド (AvgPoolとMaxPoolのConcatenateを使用)\n    x1 = GlobalMaxPooling2D(name='gmax_pool')(x)\n    x2 = GlobalAveragePooling2D(name='gavg_pool')(x)\n    x = concatenate([x1, x2], name='concat_pool')\n    \n    # 最後の活性化層はsigmoid\n    #x = Activation('sigmoid')(x) \n    x = Dense(num_classes, activation='softmax', name='predictions')(x) # 最終分類器はsoftmax\n\n    model = Model(inputs=inputs, outputs=x, name=f'resnet{depth}_{activation}_hybrid')\n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:28.658451Z","iopub.execute_input":"2025-12-16T06:58:28.658799Z","iopub.status.idle":"2025-12-16T06:58:28.675035Z","shell.execute_reply.started":"2025-12-16T06:58:28.658771Z","shell.execute_reply":"2025-12-16T06:58:28.673930Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"THRESHOLD = 0.5\n\ndef f1_score_metric(y_true, y_pred):\n    \"\"\"\n    Kaggleでよく使用されるマクロF1スコアを計算するカスタムメトリック。\n    tf.is_nan を tf.math.is_nan に修正。\n    \"\"\"\n    \n    # y_predを閾値処理してバイナリ化\n    # K.clip(y_pred, 0, 1)は確率値を0〜1にクリップ\n    y_pred_thresh = K.cast(K.greater(K.clip(y_pred, 0, 1), THRESHOLD), K.floatx())\n    \n    # True Positives (TP), False Positives (FP), False Negatives (FN) を計算\n    # 各クラスごと (axis=0 はバッチ、axis=1 はクラス)\n    tp = K.sum(y_true * y_pred_thresh, axis=0)\n    fp = K.sum((1 - y_true) * y_pred_thresh, axis=0)\n    fn = K.sum(y_true * (1 - y_pred_thresh), axis=0)\n\n    # Precision (p) と Recall (r)\n    p = tp / (tp + fp + K.epsilon())\n    r = tp / (tp + fn + K.epsilon())\n\n    # F1 Score (各クラス)\n    f1_per_class = 2 * p * r / (p + r + K.epsilon())\n    \n    # NaNの処理: 0/0 (p=0, r=0の場合)を0に設定\n    # 【修正点】tf.is_nan を tf.math.is_nan に変更\n    f1_per_class = tf.where(tf.math.is_nan(f1_per_class), tf.zeros_like(f1_per_class), f1_per_class)\n    \n    # マクロF1スコア (クラス全体の平均)\n    return K.mean(f1_per_class)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:28.676530Z","iopub.execute_input":"2025-12-16T06:58:28.676967Z","iopub.status.idle":"2025-12-16T06:58:28.703201Z","shell.execute_reply.started":"2025-12-16T06:58:28.676932Z","shell.execute_reply":"2025-12-16T06:58:28.702124Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## モデルのインスタンス化と確認","metadata":{}},{"cell_type":"code","source":"# --- モデルのインスタンス化と確認 ---\n# model_baseline = ResNet20_C_RBF_Hybrid(input_shape=(32, 32, 3), num_stages=2, depth=20, num_classes=10, activation='relu')\n# model_baseline = ResNet20_C_RBF_Hybrid(input_shape=(32, 32, 3), num_stages=2, depth=29, num_classes=10, activation='relu')\nmodel_baseline = ResNet20_C_RBF_Hybrid(input_shape=(32, 32, 3), num_stages=2, depth=38, num_classes=10, activation='relu')\n# model_baseline = ResNet20_C_RBF_Hybrid(input_shape=(32, 32, 3), num_stages=3, depth=20, num_classes=10, activation='relu')\n# model_baseline = ResNet20_C_RBF_Hybrid(input_shape=(32, 32, 3), num_stages=3, depth=29, num_classes=10, activation='relu')\n# model_baseline = ResNet20_C_RBF_Hybrid(input_shape=(32, 32, 3), num_stages=4, depth=20, num_classes=10, activation='relu')\n\n# model_baseline.compile(optimizer=Adam(learning_rate=0.001), loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\n# model_baseline.compile(optimizer=Adam(learning_rate=0.002), loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\nmodel_baseline.compile(optimizer=Adam(learning_rate=rl), loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\n\nmodel_baseline.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:28.711766Z","iopub.execute_input":"2025-12-16T06:58:28.712169Z","iopub.status.idle":"2025-12-16T06:58:29.056803Z","shell.execute_reply.started":"2025-12-16T06:58:28.712137Z","shell.execute_reply":"2025-12-16T06:58:29.055563Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_model(model_baseline, show_shapes=True, expand_nested=True, show_layer_names=True, dpi=70)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:29.057723Z","iopub.execute_input":"2025-12-16T06:58:29.058105Z","iopub.status.idle":"2025-12-16T06:58:29.338814Z","shell.execute_reply.started":"2025-12-16T06:58:29.058080Z","shell.execute_reply":"2025-12-16T06:58:29.337636Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_baseline.predict(x_train[:5])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:29.340050Z","iopub.execute_input":"2025-12-16T06:58:29.340326Z","iopub.status.idle":"2025-12-16T06:58:31.015416Z","shell.execute_reply.started":"2025-12-16T06:58:29.340306Z","shell.execute_reply":"2025-12-16T06:58:31.014406Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# モデルのウエイト保存確認\nfile_name = f'{structure}_rl{rl}_rbft{rbf_target}_epoch{num_epoch}_final.weights.h5'\nfile_name","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:58:31.016761Z","iopub.execute_input":"2025-12-16T06:58:31.017131Z","iopub.status.idle":"2025-12-16T06:58:31.024063Z","shell.execute_reply.started":"2025-12-16T06:58:31.017098Z","shell.execute_reply":"2025-12-16T06:58:31.023017Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_baseline.layers","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:59:09.099268Z","iopub.execute_input":"2025-12-16T06:59:09.099653Z","iopub.status.idle":"2025-12-16T06:59:09.107083Z","shell.execute_reply.started":"2025-12-16T06:59:09.099627Z","shell.execute_reply":"2025-12-16T06:59:09.105852Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import h5py\n\ndef save_custom_weights(model, filepath):\n    \"\"\"\n    モデルのカスタムレイヤー名と重みを対応付けてHDF5ファイルに保存する。\n    \"\"\"\n    weights_map = {}\n    for layer in model.layers:\n        # 重みを持つレイヤーのみを対象とする (Conv2DRBF, Denseなど)\n        if layer.get_weights():\n            layer_name = layer.name\n            weights = layer.get_weights()\n            weights_map[layer_name] = weights\n\n    with h5py.File(filepath, 'w') as f:\n        # メタデータを保存するルートグループ\n        weights_group = f.create_group('custom_weights')\n\n        for layer_name, weights in weights_map.items():\n            layer_group = weights_group.create_group(layer_name)\n            \n            # 各レイヤーの複数の重み (μ, γ, biasなど) を連番で保存\n            for i, w in enumerate(weights):\n                layer_group.create_dataset(str(i), data=w)\n\n    print(f\"✅ カスタム重みマップを {filepath} に保存しました。\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:59:11.228133Z","iopub.execute_input":"2025-12-16T06:59:11.228510Z","iopub.status.idle":"2025-12-16T06:59:11.237762Z","shell.execute_reply.started":"2025-12-16T06:59:11.228483Z","shell.execute_reply":"2025-12-16T06:59:11.235845Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# save_custom_weights(model_baseline, file_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:59:12.263073Z","iopub.execute_input":"2025-12-16T06:59:12.264542Z","iopub.status.idle":"2025-12-16T06:59:12.269458Z","shell.execute_reply.started":"2025-12-16T06:59:12.264482Z","shell.execute_reply":"2025-12-16T06:59:12.268127Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_custom_weights(model, filepath):\n    \"\"\"\n    HDF5ファイルからカスタム名に基づいて重みをロードし、モデルにセットする。\n    \"\"\"\n    weights_map = {}\n    \n    with h5py.File(filepath, 'r') as f:\n        weights_group = f['custom_weights']\n        \n        for layer_name in weights_group.keys():\n            layer_group = weights_group[layer_name]\n            weights = []\n            \n            # 保存されている重みを全てリストとして取得\n            i = 0\n            while str(i) in layer_group:\n                weights.append(np.array(layer_group[str(i)]))\n                i += 1\n                \n            weights_map[layer_name] = weights\n\n    # モデルに重みをセット\n    transfer_count = 0\n    for layer in model.layers:\n        layer_name = layer.name\n        \n        if layer_name in weights_map:\n            weights_to_transfer = weights_map[layer_name]\n            \n            try:\n                layer.set_weights(weights_to_transfer)\n                transfer_count += 1\n            except ValueError as e:\n                # 重みの形状が異なる場合 (通常は発生しないはず)\n                print(f\"⚠️ 警告: 重み形状が一致しないため {layer_name} の転送をスキップしました。エラー: {e}\")\n        \n    print(f\"✅ 合計 {transfer_count} 個のレイヤーの重みを {filepath} からロードしました。\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:59:12.640039Z","iopub.execute_input":"2025-12-16T06:59:12.640486Z","iopub.status.idle":"2025-12-16T06:59:12.651345Z","shell.execute_reply.started":"2025-12-16T06:59:12.640454Z","shell.execute_reply":"2025-12-16T06:59:12.649771Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## cifar-10 Conv2DRBF st2 dep29 の重みをロード","metadata":{}},{"cell_type":"code","source":"with zipfile.ZipFile('/kaggle/input/cifar-10-conv2drbf-st2-dep29-ret3/_output_.zip') as myzip:\n    with myzip.open('S2B3ret3_rl0.005_rbft0.1_epoch256_final.weights.h5') as h5file:\n        print(h5file.name)\n        load_custom_weights(model_baseline, h5file)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T06:59:42.808575Z","iopub.execute_input":"2025-12-16T06:59:42.809800Z","iopub.status.idle":"2025-12-16T06:59:46.219760Z","shell.execute_reply.started":"2025-12-16T06:59:42.809754Z","shell.execute_reply":"2025-12-16T06:59:46.218720Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 転移前の結果と同じか確認\n'''\nEpoch 256/256\n157/157 - 27s - 174ms/step - categorical_accuracy: 0.6911 - f1_score_metric: 0.6584 - loss: 0.8805 - \nval_categorical_accuracy: 0.6662 - val_f1_score_metric: 0.6316 - val_loss: 0.9557\n'''\nresults = model_baseline.evaluate(x_train, y_cat_train, batch_size=512,\n                                  verbose=1)\nresults","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-14T13:20:58.15803Z","iopub.execute_input":"2025-12-14T13:20:58.158694Z","iopub.status.idle":"2025-12-14T13:38:59.683712Z","shell.execute_reply.started":"2025-12-14T13:20:58.158667Z","shell.execute_reply":"2025-12-14T13:38:59.682782Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 一番最初のConv2dRBF\nrbf_conv_feature_extract = model_baseline.get_layer('rbf_conv2d_0_0_init')\nrbf_conv_feature_extract","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:01:36.896414Z","iopub.execute_input":"2025-12-16T07:01:36.897108Z","iopub.status.idle":"2025-12-16T07:01:36.908258Z","shell.execute_reply.started":"2025-12-16T07:01:36.897064Z","shell.execute_reply":"2025-12-16T07:01:36.906703Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"log_gamma = rbf_conv_feature_extract.get_weights()[1]\nnp.exp(log_gamma)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:01:39.764732Z","iopub.execute_input":"2025-12-16T07:01:39.765106Z","iopub.status.idle":"2025-12-16T07:01:39.776853Z","shell.execute_reply.started":"2025-12-16T07:01:39.765080Z","shell.execute_reply":"2025-12-16T07:01:39.775321Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"'''\npredictしてみる\n10分類の確率が0.1で同じなら、勾配が消失している可能性がある\n\n最後のpredictionsレイヤーへの入力が０。\n入力が０であればdenseのパラメータがどのような値であっても、\nバイアスしか出力されないので、10分類の値が同じになり、softmaxで0.1となる\n'''\nmodel_baseline.predict(x_train[:5])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:01:40.488873Z","iopub.execute_input":"2025-12-16T07:01:40.489218Z","iopub.status.idle":"2025-12-16T07:01:40.660041Z","shell.execute_reply.started":"2025-12-16T07:01:40.489198Z","shell.execute_reply":"2025-12-16T07:01:40.658972Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## model_test\n* 上記がすべて0.1と言うことは、その前のレイヤーがすべて0\n* 勾配の消失が起こっている？\n* Conv2dRBFのランドマークつまりフィルターを入力値のどれかにする\n  * 例えばfilters=16なら入力をkmeans(16)して、それぞれをフィルターにセットする\n  * 通常のGaussianLayerならランドマークは複数あるが、Conv2DRBFはフィルターとしてランドマークは一つしかないので、全エリアをカバーしないといけない\n  * ということを、上位のConv2dRBFから順次やっていく必要がある","metadata":{}},{"cell_type":"code","source":"model_baseline.layers","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:01:43.188350Z","iopub.execute_input":"2025-12-16T07:01:43.189965Z","iopub.status.idle":"2025-12-16T07:01:43.213178Z","shell.execute_reply.started":"2025-12-16T07:01:43.189860Z","shell.execute_reply":"2025-12-16T07:01:43.210114Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# concat_poolの出力を確認する\nmodel_test = Model(inputs=model_baseline.input, outputs=model_baseline.get_layer('concat_pool').output)\nmodel_test.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\nmodel_test.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:01:43.517858Z","iopub.execute_input":"2025-12-16T07:01:43.520067Z","iopub.status.idle":"2025-12-16T07:01:43.779372Z","shell.execute_reply.started":"2025-12-16T07:01:43.519812Z","shell.execute_reply":"2025-12-16T07:01:43.777966Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 「predictions」への入力がほぼ0でなければ良い\nmodel_test.predict(x_train[:5])[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:01:47.347072Z","iopub.execute_input":"2025-12-16T07:01:47.347424Z","iopub.status.idle":"2025-12-16T07:01:49.139079Z","shell.execute_reply.started":"2025-12-16T07:01:47.347396Z","shell.execute_reply":"2025-12-16T07:01:49.137966Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# SAMPLE_SIZE = 1000","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:25.184768Z","iopub.execute_input":"2025-12-15T23:43:25.185108Z","iopub.status.idle":"2025-12-15T23:43:25.189606Z","shell.execute_reply.started":"2025-12-15T23:43:25.185056Z","shell.execute_reply":"2025-12-15T23:43:25.188633Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # inputの入力と出力を見る\n# model_test = Model(inputs=model_baseline.input, outputs=model_baseline.get_layer('input').output)\n# model_test.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\n# model_test.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:25.190809Z","iopub.execute_input":"2025-12-15T23:43:25.191171Z","iopub.status.idle":"2025-12-15T23:43:25.207013Z","shell.execute_reply.started":"2025-12-15T23:43:25.191132Z","shell.execute_reply":"2025-12-15T23:43:25.205929Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# tmp = model_test.predict(x_train[:SAMPLE_SIZE])\n# tmp","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:25.209705Z","iopub.execute_input":"2025-12-15T23:43:25.210012Z","iopub.status.idle":"2025-12-15T23:43:25.225749Z","shell.execute_reply.started":"2025-12-15T23:43:25.209984Z","shell.execute_reply":"2025-12-15T23:43:25.224546Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# tmp.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:25.226963Z","iopub.execute_input":"2025-12-15T23:43:25.227229Z","iopub.status.idle":"2025-12-15T23:43:25.242568Z","shell.execute_reply.started":"2025-12-15T23:43:25.227206Z","shell.execute_reply":"2025-12-15T23:43:25.241588Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# inputs = Input(shape=(32, 32, 3))\n# x = Conv2DRBF_patch(\n#             filters=16, \n#             kernel_size=(3, 3),\n#             strides=(1, 1), \n#             padding='same', \n#             name='rbf_conv_patch'\n#         )(inputs)\n# model_test = Model(inputs=inputs, outputs=x, name=f'Conv2DRBF_patch')\n# model_test.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\n# model_test.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:25.243778Z","iopub.execute_input":"2025-12-15T23:43:25.244183Z","iopub.status.idle":"2025-12-15T23:43:25.260832Z","shell.execute_reply.started":"2025-12-15T23:43:25.244151Z","shell.execute_reply":"2025-12-15T23:43:25.259811Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# tmp = model_test.predict(x_train[:SAMPLE_SIZE])\n# tmp.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:26.00963Z","iopub.execute_input":"2025-12-15T23:43:26.009944Z","iopub.status.idle":"2025-12-15T23:43:26.015862Z","shell.execute_reply.started":"2025-12-15T23:43:26.009921Z","shell.execute_reply":"2025-12-15T23:43:26.014359Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# tmp = tmp.reshape((-1, tmp.shape[-1]))\n# tmp.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:26.188642Z","iopub.execute_input":"2025-12-15T23:43:26.188985Z","iopub.status.idle":"2025-12-15T23:43:26.193264Z","shell.execute_reply.started":"2025-12-15T23:43:26.188957Z","shell.execute_reply":"2025-12-15T23:43:26.191975Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# centers, indices = cluster.kmeans_plusplus(tmp, n_clusters=16)\n# print(centers.shape)\n# centers = centers.reshape((16,3,3,3))\n# print(centers.shape)\n# centers = np.transpose(centers, (1,2,3,0))\n# print(centers.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:26.380925Z","iopub.execute_input":"2025-12-15T23:43:26.38127Z","iopub.status.idle":"2025-12-15T23:43:26.386024Z","shell.execute_reply.started":"2025-12-15T23:43:26.381244Z","shell.execute_reply":"2025-12-15T23:43:26.384809Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# wgt = model_baseline.get_layer('rbf_conv2d_0_0_init').get_weights()\n# print(wgt[0].shape)\n# wgt[0] = centers\n# model_baseline.get_layer('rbf_conv2d_0_0_init').set_weights(wgt)\n# model_baseline.compile(optimizer=Adam(learning_rate=0.0002), loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:26.567745Z","iopub.execute_input":"2025-12-15T23:43:26.568081Z","iopub.status.idle":"2025-12-15T23:43:26.573234Z","shell.execute_reply.started":"2025-12-15T23:43:26.568053Z","shell.execute_reply":"2025-12-15T23:43:26.572045Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # inputの入力と出力を見る\n# model_test = Model(inputs=model_baseline.input, outputs=model_baseline.get_layer('rbf_conv2d_0_0_init').output)\n# model_test.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\n# model_test.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:26.8352Z","iopub.execute_input":"2025-12-15T23:43:26.835533Z","iopub.status.idle":"2025-12-15T23:43:26.840111Z","shell.execute_reply.started":"2025-12-15T23:43:26.835506Z","shell.execute_reply":"2025-12-15T23:43:26.839069Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# tmp = model_test.predict(x_train[:SAMPLE_SIZE])\n# tmp.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:28.464858Z","iopub.execute_input":"2025-12-15T23:43:28.465216Z","iopub.status.idle":"2025-12-15T23:43:28.46944Z","shell.execute_reply.started":"2025-12-15T23:43:28.465185Z","shell.execute_reply":"2025-12-15T23:43:28.468426Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# tmp = model_test.predict(x_train[:SAMPLE_SIZE])\n# tmp","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-15T23:43:28.703722Z","iopub.execute_input":"2025-12-15T23:43:28.704065Z","iopub.status.idle":"2025-12-15T23:43:28.708574Z","shell.execute_reply.started":"2025-12-15T23:43:28.704038Z","shell.execute_reply":"2025-12-15T23:43:28.70758Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## model_test2","metadata":{}},{"cell_type":"code","source":"model_test = Model(inputs=model_baseline.input, outputs=model_baseline.layers[1].output)\nmodel_test.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])\nmodel_test.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:01:55.190984Z","iopub.execute_input":"2025-12-16T07:01:55.191400Z","iopub.status.idle":"2025-12-16T07:01:55.225836Z","shell.execute_reply.started":"2025-12-16T07:01:55.191368Z","shell.execute_reply":"2025-12-16T07:01:55.224444Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred = model_test.predict(x_train[:100])\npred.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:01:55.573632Z","iopub.execute_input":"2025-12-16T07:01:55.574072Z","iopub.status.idle":"2025-12-16T07:01:55.983003Z","shell.execute_reply.started":"2025-12-16T07:01:55.574034Z","shell.execute_reply":"2025-12-16T07:01:55.982070Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = pred[ii*ncols + jj,:,:,0]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:01:57.495716Z","iopub.execute_input":"2025-12-16T07:01:57.496135Z","iopub.status.idle":"2025-12-16T07:02:09.001163Z","shell.execute_reply.started":"2025-12-16T07:01:57.496106Z","shell.execute_reply":"2025-12-16T07:02:08.999661Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = pred[ii*ncols + jj,:,:,1]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:02:09.003176Z","iopub.execute_input":"2025-12-16T07:02:09.003623Z","iopub.status.idle":"2025-12-16T07:02:21.778885Z","shell.execute_reply.started":"2025-12-16T07:02:09.003586Z","shell.execute_reply":"2025-12-16T07:02:21.777304Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = pred[ii*ncols + jj,:,:,2]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:02:21.780086Z","iopub.execute_input":"2025-12-16T07:02:21.780559Z","iopub.status.idle":"2025-12-16T07:02:34.430565Z","shell.execute_reply.started":"2025-12-16T07:02:21.780522Z","shell.execute_reply":"2025-12-16T07:02:34.429477Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = pred[ii*ncols + jj,:,:,15]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:02:34.432729Z","iopub.execute_input":"2025-12-16T07:02:34.433370Z","iopub.status.idle":"2025-12-16T07:02:45.585995Z","shell.execute_reply.started":"2025-12-16T07:02:34.433338Z","shell.execute_reply":"2025-12-16T07:02:45.584509Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Train","metadata":{}},{"cell_type":"code","source":"%%time\nhst = model_baseline.fit(x_train, y_cat_train, batch_size=512,\n                         #validation_data=(x_val, y_cat_val),\n                         #epochs=64,\n                         epochs=num_epoch,\n                         verbose=2,\n                         #callbacks=callbacks,\n                         validation_split=0.2\n                        )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-09T15:21:19.408155Z","iopub.execute_input":"2025-12-09T15:21:19.408411Z","iopub.status.idle":"2025-12-09T15:22:43.784144Z","shell.execute_reply.started":"2025-12-09T15:21:19.408393Z","shell.execute_reply":"2025-12-09T15:22:43.78345Z"},"_kg_hide-output":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(file_name)\nsave_custom_weights(model_baseline, file_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T07:03:45.861665Z","iopub.execute_input":"2025-12-16T07:03:45.862157Z","iopub.status.idle":"2025-12-16T07:03:45.922470Z","shell.execute_reply.started":"2025-12-16T07:03:45.862123Z","shell.execute_reply":"2025-12-16T07:03:45.920560Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"hst_history = hst.history\nfig, ax = plt.subplots(1, 3, figsize=(20,5))\nax[0].set_title('loss')\nax[0].plot(list(range(len(hst_history[\"loss\"]))), hst_history[\"loss\"], label=\"Train loss\")\nax[0].plot(list(range(len(hst_history[\"loss\"]))), hst_history[\"val_loss\"], label=\"val loss\")\nax[1].set_title('acc')\nax[1].plot(list(range(len(hst_history[\"loss\"]))), hst_history[\"categorical_accuracy\"], label=\"categorical_accuracy\")\nax[1].plot(list(range(len(hst_history[\"loss\"]))), hst_history[\"val_categorical_accuracy\"], label=\"val categorical_accuracy\")\nax[2].set_title('f1_score')\nax[2].plot(list(range(len(hst_history[\"loss\"]))), hst_history[\"f1_score_metric\"], label=\"f1 score\")\nax[2].plot(list(range(len(hst_history[\"loss\"]))), hst_history[\"val_f1_score_metric\"], label=\"val f1 score\")\nax[0].legend()\nax[1].legend()\nax[2].legend()\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T03:49:00.200416Z","iopub.execute_input":"2025-12-08T03:49:00.200676Z","iopub.status.idle":"2025-12-08T03:49:00.96197Z","shell.execute_reply.started":"2025-12-08T03:49:00.200659Z","shell.execute_reply":"2025-12-08T03:49:00.961406Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"log_gamma = rbf_conv_feature_extract.get_weights()[1]\nnp.exp(log_gamma)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-09T00:36:04.948432Z","iopub.execute_input":"2025-12-09T00:36:04.948741Z","iopub.status.idle":"2025-12-09T00:36:04.958161Z","shell.execute_reply.started":"2025-12-09T00:36:04.948717Z","shell.execute_reply":"2025-12-09T00:36:04.957144Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred = model_test.predict(x_train[:100])\npred.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-09T00:36:28.676098Z","iopub.execute_input":"2025-12-09T00:36:28.676849Z","iopub.status.idle":"2025-12-09T00:36:29.000005Z","shell.execute_reply.started":"2025-12-09T00:36:28.676819Z","shell.execute_reply":"2025-12-09T00:36:28.999031Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = pred[ii*ncols + jj,:,:,0]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-09T00:36:30.285193Z","iopub.execute_input":"2025-12-09T00:36:30.285787Z","iopub.status.idle":"2025-12-09T00:36:40.765547Z","shell.execute_reply.started":"2025-12-09T00:36:30.285759Z","shell.execute_reply":"2025-12-09T00:36:40.764273Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = pred[ii*ncols + jj,:,:,1]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-09T00:36:40.767795Z","iopub.execute_input":"2025-12-09T00:36:40.7688Z","iopub.status.idle":"2025-12-09T00:36:52.521191Z","shell.execute_reply.started":"2025-12-09T00:36:40.768762Z","shell.execute_reply":"2025-12-09T00:36:52.520087Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = pred[ii*ncols + jj,:,:,2]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-09T00:36:52.522252Z","iopub.execute_input":"2025-12-09T00:36:52.522535Z","iopub.status.idle":"2025-12-09T00:37:04.081058Z","shell.execute_reply.started":"2025-12-09T00:36:52.522514Z","shell.execute_reply":"2025-12-09T00:37:04.080022Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"nrows=10\nncols=10\nfig, subs = plt.subplots(nrows=nrows, ncols=ncols, figsize=(15, 10))\n\nfor ii in range(nrows):\n    for jj in range(ncols):\n        iplt = subs[ii, jj]\n        img_array = pred[ii*ncols + jj,:,:,15]\n        iplt.imshow(img_array)\n\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-09T00:37:04.082683Z","iopub.execute_input":"2025-12-09T00:37:04.082965Z","iopub.status.idle":"2025-12-09T00:37:15.885965Z","shell.execute_reply.started":"2025-12-09T00:37:04.082943Z","shell.execute_reply":"2025-12-09T00:37:15.884589Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 予測結果をKaggle CIFAR-10の提出ファイル形式に変換し、表示します。","metadata":{}},{"cell_type":"code","source":"predictions = model_baseline.predict(x_test, verbose=1)\npredictions.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T03:49:43.295162Z","iopub.execute_input":"2025-12-08T03:49:43.296094Z","iopub.status.idle":"2025-12-08T03:50:45.065847Z","shell.execute_reply.started":"2025-12-08T03:49:43.296049Z","shell.execute_reply":"2025-12-08T03:50:45.065139Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 予測されたクラス (最も高い確率を持つインデックス)\npredicted_classes = np.argmax(predictions, axis=1)\npredicted_classes_name = [id_key[ee] for ee in predicted_classes]\n\nsubmission_file = sampleSubmission.copy()\nsubmission_file['label'] = predicted_classes_name\nsubmission_file","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T03:50:45.067159Z","iopub.execute_input":"2025-12-08T03:50:45.067465Z","iopub.status.idle":"2025-12-08T03:50:45.137032Z","shell.execute_reply.started":"2025-12-08T03:50:45.067447Z","shell.execute_reply":"2025-12-08T03:50:45.136356Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"submission_file.to_csv('submission.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-08T03:50:45.137904Z","iopub.execute_input":"2025-12-08T03:50:45.138159Z","iopub.status.idle":"2025-12-08T03:50:45.361721Z","shell.execute_reply.started":"2025-12-08T03:50:45.138126Z","shell.execute_reply":"2025-12-08T03:50:45.361123Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# def create_submission_file(predictions):\n#     \"\"\"\n#     予測結果をKaggle Digit Recognizerの提出ファイル形式に変換し、表示します。\n#     \"\"\"\n#     # 予測されたクラス (最も高い確率を持つインデックス)\n#     predicted_classes = np.argmax(predictions, axis=1)\n    \n#     # Kaggle提出形式: ImageId,Label\n#     # ImageId は 1 から始まる\n#     image_ids = np.arange(1, len(predicted_classes) + 1)\n    \n#     # CSV形式の文字列を構築\n#     submission_content = \"ImageId,Label\\n\"\n#     for img_id, label in zip(image_ids, predicted_classes):\n#         submission_content += f\"{img_id},{label}\\n\"\n        \n#     # ファイルとして出力\n#     with open(\"submission.csv\", \"w\") as f:\n#         f.write(submission_content)\n        \n#     # 最初と最後の数行を表示\n#     print(\"\\n--- Submission File Preview (Kaggle Format) ---\")\n#     print(submission_content.split('\\n')[0])\n#     for line in submission_content.split('\\n')[1:6]:\n#         print(line)\n#     print(\"...\")\n#     for line in submission_content.split('\\n')[-6:-1]:\n#         print(line)\n#     print(f\"\\nTotal predictions generated: {len(predicted_classes)}\")\n#     print(\"\\n✅ Submission file 'submission.csv' generated for download.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-11-30T00:45:09.170059Z","iopub.execute_input":"2025-11-30T00:45:09.170325Z","iopub.status.idle":"2025-11-30T00:45:09.174189Z","shell.execute_reply.started":"2025-11-30T00:45:09.170299Z","shell.execute_reply":"2025-11-30T00:45:09.173651Z"}},"outputs":[],"execution_count":null}]}