{"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":286541877,"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-16T14:46:57.346684Z","iopub.execute_input":"2025-12-16T14:46:57.347031Z","iopub.status.idle":"2025-12-16T14:48:24.743881Z","shell.execute_reply.started":"2025-12-16T14:46:57.346981Z","shell.execute_reply":"2025-12-16T14:48:24.741775Z"},"_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-16T14:48:24.747034Z","iopub.execute_input":"2025-12-16T14:48:24.747496Z","iopub.status.idle":"2025-12-16T14:48:48.445051Z","shell.execute_reply.started":"2025-12-16T14:48:24.747459Z","shell.execute_reply":"2025-12-16T14:48:48.443804Z"},"_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-16T14:48:48.446806Z","iopub.execute_input":"2025-12-16T14:48:48.447209Z","iopub.status.idle":"2025-12-16T14:49:00.141453Z","shell.execute_reply.started":"2025-12-16T14:48:48.447147Z","shell.execute_reply":"2025-12-16T14:49:00.140472Z"}},"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-16T14:49:00.143573Z","iopub.execute_input":"2025-12-16T14:49:00.144303Z","iopub.status.idle":"2025-12-16T14:49:00.151990Z","shell.execute_reply.started":"2025-12-16T14:49:00.144272Z","shell.execute_reply":"2025-12-16T14:49:00.150946Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ! pip install libarchive-c","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:49:00.153185Z","iopub.execute_input":"2025-12-16T14:49:00.153493Z","iopub.status.idle":"2025-12-16T14:49:00.172419Z","shell.execute_reply.started":"2025-12-16T14:49:00.153459Z","shell.execute_reply":"2025-12-16T14:49:00.171191Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"! pip install py7zr","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:49:00.173375Z","iopub.execute_input":"2025-12-16T14:49:00.173628Z","iopub.status.idle":"2025-12-16T14:49:06.907804Z","shell.execute_reply.started":"2025-12-16T14:49:00.173609Z","shell.execute_reply":"2025-12-16T14:49:06.906590Z"},"_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-16T14:49:06.909389Z","iopub.execute_input":"2025-12-16T14:49:06.909675Z","iopub.status.idle":"2025-12-16T14:49:06.998759Z","shell.execute_reply.started":"2025-12-16T14:49:06.909647Z","shell.execute_reply":"2025-12-16T14:49:06.997691Z"}},"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-16T14:49:07.000142Z","iopub.execute_input":"2025-12-16T14:49:07.000552Z","iopub.status.idle":"2025-12-16T14:49:41.976664Z","shell.execute_reply.started":"2025-12-16T14:49:07.000526Z","shell.execute_reply":"2025-12-16T14:49:41.975703Z"}},"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-16T14:49:41.977748Z","iopub.execute_input":"2025-12-16T14:49:41.978529Z","iopub.status.idle":"2025-12-16T14:49:54.146253Z","shell.execute_reply.started":"2025-12-16T14:49:41.978503Z","shell.execute_reply":"2025-12-16T14:49:54.145039Z"},"_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-16T14:49:54.150201Z","iopub.execute_input":"2025-12-16T14:49:54.150525Z","iopub.status.idle":"2025-12-16T14:49:54.309180Z","shell.execute_reply.started":"2025-12-16T14:49:54.150494Z","shell.execute_reply":"2025-12-16T14:49:54.308196Z"}},"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-16T14:49:54.310273Z","iopub.execute_input":"2025-12-16T14:49:54.311048Z","iopub.status.idle":"2025-12-16T14:49:54.317009Z","shell.execute_reply.started":"2025-12-16T14:49:54.311019Z","shell.execute_reply":"2025-12-16T14:49:54.315915Z"}},"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-16T14:49:54.318509Z","iopub.execute_input":"2025-12-16T14:49:54.318865Z","iopub.status.idle":"2025-12-16T14:49:54.335375Z","shell.execute_reply.started":"2025-12-16T14:49:54.318835Z","shell.execute_reply":"2025-12-16T14:49:54.334326Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"! mkdir img","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:49:54.336490Z","iopub.execute_input":"2025-12-16T14:49:54.336771Z","iopub.status.idle":"2025-12-16T14:49:54.503020Z","shell.execute_reply.started":"2025-12-16T14:49:54.336749Z","shell.execute_reply":"2025-12-16T14:49:54.501487Z"}},"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-16T14:49:54.504487Z","iopub.execute_input":"2025-12-16T14:49:54.505349Z","iopub.status.idle":"2025-12-16T14:49:54.512599Z","shell.execute_reply.started":"2025-12-16T14:49:54.505312Z","shell.execute_reply":"2025-12-16T14:49:54.511429Z"}},"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-16T14:49:54.513919Z","iopub.execute_input":"2025-12-16T14:49:54.514581Z","iopub.status.idle":"2025-12-16T14:49:54.531446Z","shell.execute_reply.started":"2025-12-16T14:49:54.514547Z","shell.execute_reply":"2025-12-16T14:49:54.530330Z"}},"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-16T14:49:54.532868Z","iopub.execute_input":"2025-12-16T14:49:54.533302Z","iopub.status.idle":"2025-12-16T14:50:22.573277Z","shell.execute_reply.started":"2025-12-16T14:49:54.533279Z","shell.execute_reply":"2025-12-16T14:50:22.572187Z"}},"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-16T14:50:22.574352Z","iopub.execute_input":"2025-12-16T14:50:22.574627Z","iopub.status.idle":"2025-12-16T14:50:22.641433Z","shell.execute_reply.started":"2025-12-16T14:50:22.574606Z","shell.execute_reply":"2025-12-16T14:50:22.640194Z"}},"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-16T14:50:22.642726Z","iopub.execute_input":"2025-12-16T14:50:22.643142Z","iopub.status.idle":"2025-12-16T14:50:31.646725Z","shell.execute_reply.started":"2025-12-16T14:50:22.643109Z","shell.execute_reply":"2025-12-16T14:50:31.645800Z"}},"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-16T14:50:31.648275Z","iopub.execute_input":"2025-12-16T14:50:31.649134Z","iopub.status.idle":"2025-12-16T14:50:32.358889Z","shell.execute_reply.started":"2025-12-16T14:50:31.649081Z","shell.execute_reply":"2025-12-16T14:50:32.358127Z"}},"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-16T14:50:32.359757Z","iopub.execute_input":"2025-12-16T14:50:32.359970Z","iopub.status.idle":"2025-12-16T14:50:32.366783Z","shell.execute_reply.started":"2025-12-16T14:50:32.359952Z","shell.execute_reply":"2025-12-16T14:50:32.365767Z"}},"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-16T14:50:32.368251Z","iopub.execute_input":"2025-12-16T14:50:32.369206Z","iopub.status.idle":"2025-12-16T14:50:33.359494Z","shell.execute_reply.started":"2025-12-16T14:50:32.369171Z","shell.execute_reply":"2025-12-16T14:50:33.358400Z"}},"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-16T14:50:33.360688Z","iopub.execute_input":"2025-12-16T14:50:33.361325Z","iopub.status.idle":"2025-12-16T14:53:13.803110Z","shell.execute_reply.started":"2025-12-16T14:50:33.361298Z","shell.execute_reply":"2025-12-16T14:53:13.801995Z"}},"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-16T14:53:13.804539Z","iopub.execute_input":"2025-12-16T14:53:13.805422Z","iopub.status.idle":"2025-12-16T14:53:14.210583Z","shell.execute_reply.started":"2025-12-16T14:53:13.805394Z","shell.execute_reply":"2025-12-16T14:53:14.209656Z"}},"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-16T14:53:14.211641Z","iopub.execute_input":"2025-12-16T14:53:14.211952Z","iopub.status.idle":"2025-12-16T14:54:05.117800Z","shell.execute_reply.started":"2025-12-16T14:53:14.211930Z","shell.execute_reply":"2025-12-16T14:54:05.116780Z"}},"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-16T14:54:05.118739Z","iopub.execute_input":"2025-12-16T14:54:05.119056Z","iopub.status.idle":"2025-12-16T14:54:08.357338Z","shell.execute_reply.started":"2025-12-16T14:54:05.119025Z","shell.execute_reply":"2025-12-16T14:54:08.356421Z"}},"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-16T14:54:08.358328Z","iopub.execute_input":"2025-12-16T14:54:08.358647Z","iopub.status.idle":"2025-12-16T14:54:08.541823Z","shell.execute_reply.started":"2025-12-16T14:54:08.358614Z","shell.execute_reply":"2025-12-16T14:54:08.540995Z"}},"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-16T14:54:08.542809Z","iopub.execute_input":"2025-12-16T14:54:08.543164Z","iopub.status.idle":"2025-12-16T14:54:08.579496Z","shell.execute_reply.started":"2025-12-16T14:54:08.543135Z","shell.execute_reply":"2025-12-16T14:54:08.578541Z"}},"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-16T14:54:08.589184Z","iopub.execute_input":"2025-12-16T14:54:08.589496Z","iopub.status.idle":"2025-12-16T14:54:08.627578Z","shell.execute_reply.started":"2025-12-16T14:54:08.589474Z","shell.execute_reply":"2025-12-16T14:54:08.626630Z"}},"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-16T14:54:08.628637Z","iopub.execute_input":"2025-12-16T14:54:08.629048Z","iopub.status.idle":"2025-12-16T14:54:08.650185Z","shell.execute_reply.started":"2025-12-16T14:54:08.629023Z","shell.execute_reply":"2025-12-16T14:54:08.649231Z"}},"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-16T14:54:08.651410Z","iopub.execute_input":"2025-12-16T14:54:08.652505Z","iopub.status.idle":"2025-12-16T14:54:08.670454Z","shell.execute_reply.started":"2025-12-16T14:54:08.652480Z","shell.execute_reply":"2025-12-16T14:54:08.669534Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"np.unique(y_labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:54:08.671500Z","iopub.execute_input":"2025-12-16T14:54:08.671864Z","iopub.status.idle":"2025-12-16T14:54:08.696200Z","shell.execute_reply.started":"2025-12-16T14:54:08.671842Z","shell.execute_reply":"2025-12-16T14:54:08.695262Z"}},"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-16T14:54:08.697213Z","iopub.execute_input":"2025-12-16T14:54:08.697458Z","iopub.status.idle":"2025-12-16T14:54:08.889844Z","shell.execute_reply.started":"2025-12-16T14:54:08.697430Z","shell.execute_reply":"2025-12-16T14:54:08.889024Z"}},"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-16T14:54:08.890825Z","iopub.execute_input":"2025-12-16T14:54:08.891199Z","iopub.status.idle":"2025-12-16T14:54:08.937025Z","shell.execute_reply.started":"2025-12-16T14:54:08.891169Z","shell.execute_reply":"2025-12-16T14:54:08.936154Z"}},"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-16T14:54:08.938166Z","iopub.execute_input":"2025-12-16T14:54:08.938574Z","iopub.status.idle":"2025-12-16T14:54:09.011554Z","shell.execute_reply.started":"2025-12-16T14:54:08.938548Z","shell.execute_reply":"2025-12-16T14:54:09.010594Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.imshow(img_array)\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:54:09.012681Z","iopub.execute_input":"2025-12-16T14:54:09.013013Z","iopub.status.idle":"2025-12-16T14:54:09.293865Z","shell.execute_reply.started":"2025-12-16T14:54:09.012983Z","shell.execute_reply":"2025-12-16T14:54:09.292729Z"}},"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-16T14:54:09.294944Z","iopub.execute_input":"2025-12-16T14:54:09.295252Z","iopub.status.idle":"2025-12-16T14:54:09.318749Z","shell.execute_reply.started":"2025-12-16T14:54:09.295229Z","shell.execute_reply":"2025-12-16T14:54:09.317737Z"}},"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-16T14:54:09.319871Z","iopub.execute_input":"2025-12-16T14:54:09.320283Z","iopub.status.idle":"2025-12-16T14:54:09.325412Z","shell.execute_reply.started":"2025-12-16T14:54:09.320260Z","shell.execute_reply":"2025-12-16T14:54:09.323954Z"}},"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-16T14:54:09.326555Z","iopub.execute_input":"2025-12-16T14:54:09.326867Z","iopub.status.idle":"2025-12-16T14:54:09.342635Z","shell.execute_reply.started":"2025-12-16T14:54:09.326832Z","shell.execute_reply":"2025-12-16T14:54:09.341591Z"}},"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-16T14:54:09.343811Z","iopub.execute_input":"2025-12-16T14:54:09.344200Z","iopub.status.idle":"2025-12-16T14:54:09.359543Z","shell.execute_reply.started":"2025-12-16T14:54:09.344177Z","shell.execute_reply":"2025-12-16T14:54:09.358593Z"}},"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-16T14:54:09.360711Z","iopub.execute_input":"2025-12-16T14:54:09.361501Z","iopub.status.idle":"2025-12-16T14:54:09.387562Z","shell.execute_reply.started":"2025-12-16T14:54:09.361468Z","shell.execute_reply":"2025-12-16T14:54:09.386426Z"}},"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-16T14:54:09.388848Z","iopub.execute_input":"2025-12-16T14:54:09.389209Z","iopub.status.idle":"2025-12-16T14:54:19.677165Z","shell.execute_reply.started":"2025-12-16T14:54:09.389175Z","shell.execute_reply":"2025-12-16T14:54:19.675599Z"}},"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-16T14:54:19.678600Z","iopub.execute_input":"2025-12-16T14:54:19.679011Z","iopub.status.idle":"2025-12-16T14:54:31.116352Z","shell.execute_reply.started":"2025-12-16T14:54:19.678978Z","shell.execute_reply":"2025-12-16T14:54:31.115181Z"}},"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-16T14:54:31.117768Z","iopub.execute_input":"2025-12-16T14:54:31.118054Z","iopub.status.idle":"2025-12-16T14:54:44.587254Z","shell.execute_reply.started":"2025-12-16T14:54:31.118031Z","shell.execute_reply":"2025-12-16T14:54:44.585984Z"}},"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-16T14:54:44.588914Z","iopub.execute_input":"2025-12-16T14:54:44.589362Z","iopub.status.idle":"2025-12-16T14:54:54.890695Z","shell.execute_reply.started":"2025-12-16T14:54:44.589322Z","shell.execute_reply":"2025-12-16T14:54:54.889109Z"}},"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-16T14:54:54.892333Z","iopub.execute_input":"2025-12-16T14:54:54.892786Z","iopub.status.idle":"2025-12-16T14:54:54.899505Z","shell.execute_reply.started":"2025-12-16T14:54:54.892735Z","shell.execute_reply":"2025-12-16T14:54:54.898599Z"}},"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-16T14:54:54.900698Z","iopub.execute_input":"2025-12-16T14:54:54.901057Z","iopub.status.idle":"2025-12-16T14:54:54.926358Z","shell.execute_reply.started":"2025-12-16T14:54:54.901028Z","shell.execute_reply":"2025-12-16T14:54:54.925379Z"}},"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-16T14:54:54.927629Z","iopub.execute_input":"2025-12-16T14:54:54.928369Z","iopub.status.idle":"2025-12-16T14:54:54.946149Z","shell.execute_reply.started":"2025-12-16T14:54:54.928341Z","shell.execute_reply":"2025-12-16T14:54:54.944960Z"}},"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-16T14:54:54.947352Z","iopub.execute_input":"2025-12-16T14:54:54.947816Z","iopub.status.idle":"2025-12-16T14:54:54.972845Z","shell.execute_reply.started":"2025-12-16T14:54:54.947791Z","shell.execute_reply":"2025-12-16T14:54:54.971939Z"}},"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-16T14:54:54.974241Z","iopub.execute_input":"2025-12-16T14:54:54.974553Z","iopub.status.idle":"2025-12-16T14:54:55.010468Z","shell.execute_reply.started":"2025-12-16T14:54:54.974533Z","shell.execute_reply":"2025-12-16T14:54:55.009316Z"}},"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-16T14:54:55.011619Z","iopub.execute_input":"2025-12-16T14:54:55.011920Z","iopub.status.idle":"2025-12-16T14:54:55.108270Z","shell.execute_reply.started":"2025-12-16T14:54:55.011886Z","shell.execute_reply":"2025-12-16T14:54:55.107406Z"}},"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-16T14:54:55.109347Z","iopub.execute_input":"2025-12-16T14:54:55.109682Z","iopub.status.idle":"2025-12-16T14:54:55.144172Z","shell.execute_reply.started":"2025-12-16T14:54:55.109653Z","shell.execute_reply":"2025-12-16T14:54:55.143278Z"}},"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-16T14:54:55.145279Z","iopub.execute_input":"2025-12-16T14:54:55.145573Z","iopub.status.idle":"2025-12-16T14:54:55.157507Z","shell.execute_reply.started":"2025-12-16T14:54:55.145541Z","shell.execute_reply":"2025-12-16T14:54:55.156486Z"}},"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-16T14:54:55.158613Z","iopub.execute_input":"2025-12-16T14:54:55.158968Z","iopub.status.idle":"2025-12-16T14:54:55.190625Z","shell.execute_reply.started":"2025-12-16T14:54:55.158945Z","shell.execute_reply":"2025-12-16T14:54:55.189871Z"}},"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-16T14:54:55.191630Z","iopub.execute_input":"2025-12-16T14:54:55.191970Z","iopub.status.idle":"2025-12-16T14:54:55.201314Z","shell.execute_reply.started":"2025-12-16T14:54:55.191947Z","shell.execute_reply":"2025-12-16T14:54:55.200450Z"}},"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-16T14:54:55.202337Z","iopub.execute_input":"2025-12-16T14:54:55.203028Z","iopub.status.idle":"2025-12-16T14:54:55.420365Z","shell.execute_reply.started":"2025-12-16T14:54:55.202992Z","shell.execute_reply":"2025-12-16T14:54:55.419515Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred_tmp[0,:,:,0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:54:55.421431Z","iopub.execute_input":"2025-12-16T14:54:55.421775Z","iopub.status.idle":"2025-12-16T14:54:55.429423Z","shell.execute_reply.started":"2025-12-16T14:54:55.421743Z","shell.execute_reply":"2025-12-16T14:54:55.428466Z"}},"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-16T14:54:55.430322Z","iopub.execute_input":"2025-12-16T14:54:55.430599Z","iopub.status.idle":"2025-12-16T14:54:55.448188Z","shell.execute_reply.started":"2025-12-16T14:54:55.430571Z","shell.execute_reply":"2025-12-16T14:54:55.447160Z"}},"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-16T14:54:55.449276Z","iopub.execute_input":"2025-12-16T14:54:55.449680Z","iopub.status.idle":"2025-12-16T14:54:55.463004Z","shell.execute_reply.started":"2025-12-16T14:54:55.449657Z","shell.execute_reply":"2025-12-16T14:54:55.462183Z"}},"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-16T14:54:55.464222Z","iopub.execute_input":"2025-12-16T14:54:55.464503Z","iopub.status.idle":"2025-12-16T14:54:55.528033Z","shell.execute_reply.started":"2025-12-16T14:54:55.464473Z","shell.execute_reply":"2025-12-16T14:54:55.527198Z"}},"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-16T14:54:55.529057Z","iopub.execute_input":"2025-12-16T14:54:55.529756Z","iopub.status.idle":"2025-12-16T14:54:55.554996Z","shell.execute_reply.started":"2025-12-16T14:54:55.529687Z","shell.execute_reply":"2025-12-16T14:54:55.554251Z"}},"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-16T14:54:55.556211Z","iopub.execute_input":"2025-12-16T14:54:55.556543Z","iopub.status.idle":"2025-12-16T14:54:55.777819Z","shell.execute_reply.started":"2025-12-16T14:54:55.556514Z","shell.execute_reply":"2025-12-16T14:54:55.776805Z"}},"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-16T14:54:55.778933Z","iopub.execute_input":"2025-12-16T14:54:55.779286Z","iopub.status.idle":"2025-12-16T14:54:55.974931Z","shell.execute_reply.started":"2025-12-16T14:54:55.779250Z","shell.execute_reply":"2025-12-16T14:54:55.974108Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:54:55.976168Z","iopub.execute_input":"2025-12-16T14:54:55.976506Z","iopub.status.idle":"2025-12-16T14:54:55.983404Z","shell.execute_reply.started":"2025-12-16T14:54:55.976483Z","shell.execute_reply":"2025-12-16T14:54:55.982398Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"hybrid_model.layers","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:54:55.984720Z","iopub.execute_input":"2025-12-16T14:54:55.985140Z","iopub.status.idle":"2025-12-16T14:54:56.003075Z","shell.execute_reply.started":"2025-12-16T14:54:55.985082Z","shell.execute_reply":"2025-12-16T14:54:56.002174Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"hybrid_model.layers[1].output","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:54:56.004221Z","iopub.execute_input":"2025-12-16T14:54:56.004674Z","iopub.status.idle":"2025-12-16T14:54:56.022752Z","shell.execute_reply.started":"2025-12-16T14:54:56.004651Z","shell.execute_reply":"2025-12-16T14:54:56.021744Z"}},"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-16T14:54:56.023873Z","iopub.execute_input":"2025-12-16T14:54:56.024279Z","iopub.status.idle":"2025-12-16T14:54:56.054023Z","shell.execute_reply.started":"2025-12-16T14:54:56.024249Z","shell.execute_reply":"2025-12-16T14:54:56.053005Z"}},"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-16T14:54:56.055161Z","iopub.execute_input":"2025-12-16T14:54:56.055464Z","iopub.status.idle":"2025-12-16T14:54:56.109193Z","shell.execute_reply.started":"2025-12-16T14:54:56.055438Z","shell.execute_reply":"2025-12-16T14:54:56.108197Z"}},"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-16T14:54:56.110219Z","iopub.execute_input":"2025-12-16T14:54:56.110530Z","iopub.status.idle":"2025-12-16T14:54:56.116835Z","shell.execute_reply.started":"2025-12-16T14:54:56.110499Z","shell.execute_reply":"2025-12-16T14:54:56.116016Z"}},"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-16T14:54:56.117828Z","iopub.execute_input":"2025-12-16T14:54:56.118157Z","iopub.status.idle":"2025-12-16T14:54:56.133233Z","shell.execute_reply.started":"2025-12-16T14:54:56.118128Z","shell.execute_reply":"2025-12-16T14:54:56.132206Z"}},"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-16T14:54:56.134325Z","iopub.execute_input":"2025-12-16T14:54:56.134761Z","iopub.status.idle":"2025-12-16T14:54:56.153667Z","shell.execute_reply.started":"2025-12-16T14:54:56.134727Z","shell.execute_reply":"2025-12-16T14:54:56.152734Z"}},"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-16T14:54:56.154761Z","iopub.execute_input":"2025-12-16T14:54:56.155088Z","iopub.status.idle":"2025-12-16T14:54:56.171424Z","shell.execute_reply.started":"2025-12-16T14:54:56.155054Z","shell.execute_reply":"2025-12-16T14:54:56.170418Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"filters.reshape(-1, filters.shape[-1]).shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:54:56.172732Z","iopub.execute_input":"2025-12-16T14:54:56.173085Z","iopub.status.idle":"2025-12-16T14:54:56.190982Z","shell.execute_reply.started":"2025-12-16T14:54:56.173054Z","shell.execute_reply":"2025-12-16T14:54:56.190079Z"}},"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-16T14:54:56.191925Z","iopub.execute_input":"2025-12-16T14:54:56.192222Z","iopub.status.idle":"2025-12-16T14:54:59.703151Z","shell.execute_reply.started":"2025-12-16T14:54:56.192200Z","shell.execute_reply":"2025-12-16T14:54:59.702177Z"}},"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-16T14:54:59.704277Z","iopub.execute_input":"2025-12-16T14:54:59.704658Z","iopub.status.idle":"2025-12-16T14:55:02.410731Z","shell.execute_reply.started":"2025-12-16T14:54:59.704637Z","shell.execute_reply":"2025-12-16T14:55:02.409848Z"}},"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-16T14:55:02.411889Z","iopub.execute_input":"2025-12-16T14:55:02.412235Z","iopub.status.idle":"2025-12-16T14:55:02.419035Z","shell.execute_reply.started":"2025-12-16T14:55:02.412207Z","shell.execute_reply":"2025-12-16T14:55:02.418128Z"}},"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 = 'S2B4ret'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:55:02.420304Z","iopub.execute_input":"2025-12-16T14:55:02.421208Z","iopub.status.idle":"2025-12-16T14:55:02.438561Z","shell.execute_reply.started":"2025-12-16T14:55:02.421174Z","shell.execute_reply":"2025-12-16T14:55:02.437602Z"}},"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-16T14:55:02.439693Z","iopub.execute_input":"2025-12-16T14:55:02.440922Z","iopub.status.idle":"2025-12-16T14:55:02.457878Z","shell.execute_reply.started":"2025-12-16T14:55:02.440894Z","shell.execute_reply":"2025-12-16T14:55:02.456824Z"}},"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-16T14:55:02.459026Z","iopub.execute_input":"2025-12-16T14:55:02.459452Z","iopub.status.idle":"2025-12-16T14:55:02.516137Z","shell.execute_reply.started":"2025-12-16T14:55:02.459418Z","shell.execute_reply":"2025-12-16T14:55:02.515034Z"}},"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-16T14:55:02.517369Z","iopub.execute_input":"2025-12-16T14:55:02.517709Z","iopub.status.idle":"2025-12-16T14:55:02.568858Z","shell.execute_reply.started":"2025-12-16T14:55:02.517680Z","shell.execute_reply":"2025-12-16T14:55:02.567922Z"}},"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-16T14:55:02.569889Z","iopub.execute_input":"2025-12-16T14:55:02.570254Z","iopub.status.idle":"2025-12-16T14:55:02.587465Z","shell.execute_reply.started":"2025-12-16T14:55:02.570220Z","shell.execute_reply":"2025-12-16T14:55:02.586390Z"}},"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-16T14:55:02.588689Z","iopub.execute_input":"2025-12-16T14:55:02.588980Z","iopub.status.idle":"2025-12-16T14:55:02.612384Z","shell.execute_reply.started":"2025-12-16T14:55:02.588958Z","shell.execute_reply":"2025-12-16T14:55:02.611368Z"}},"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-16T14:55:02.621977Z","iopub.execute_input":"2025-12-16T14:55:02.622649Z","iopub.status.idle":"2025-12-16T14:55:02.928355Z","shell.execute_reply.started":"2025-12-16T14:55:02.622618Z","shell.execute_reply":"2025-12-16T14:55:02.927238Z"},"_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-16T14:55:02.929290Z","iopub.execute_input":"2025-12-16T14:55:02.929605Z","iopub.status.idle":"2025-12-16T14:55:03.205058Z","shell.execute_reply.started":"2025-12-16T14:55:02.929571Z","shell.execute_reply":"2025-12-16T14:55:03.204180Z"},"_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-16T14:55:03.206231Z","iopub.execute_input":"2025-12-16T14:55:03.206503Z","iopub.status.idle":"2025-12-16T14:55:04.779186Z","shell.execute_reply.started":"2025-12-16T14:55:03.206482Z","shell.execute_reply":"2025-12-16T14:55:04.778172Z"}},"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-16T14:55:04.780340Z","iopub.execute_input":"2025-12-16T14:55:04.780619Z","iopub.status.idle":"2025-12-16T14:55:04.787144Z","shell.execute_reply.started":"2025-12-16T14:55:04.780591Z","shell.execute_reply":"2025-12-16T14:55:04.786192Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_baseline.layers","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:55:04.788235Z","iopub.execute_input":"2025-12-16T14:55:04.788572Z","iopub.status.idle":"2025-12-16T14:55:04.806525Z","shell.execute_reply.started":"2025-12-16T14:55:04.788543Z","shell.execute_reply":"2025-12-16T14:55:04.805677Z"}},"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-16T14:55:04.807408Z","iopub.execute_input":"2025-12-16T14:55:04.807734Z","iopub.status.idle":"2025-12-16T14:55:04.823238Z","shell.execute_reply.started":"2025-12-16T14:55:04.807692Z","shell.execute_reply":"2025-12-16T14:55:04.822323Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# save_custom_weights(model_baseline, file_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:55:04.824187Z","iopub.execute_input":"2025-12-16T14:55:04.824489Z","iopub.status.idle":"2025-12-16T14:55:04.843419Z","shell.execute_reply.started":"2025-12-16T14:55:04.824467Z","shell.execute_reply":"2025-12-16T14:55:04.842134Z"}},"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-16T14:55:04.844598Z","iopub.execute_input":"2025-12-16T14:55:04.845660Z","iopub.status.idle":"2025-12-16T14:55:04.864160Z","shell.execute_reply.started":"2025-12-16T14:55:04.845623Z","shell.execute_reply":"2025-12-16T14:55:04.862836Z"}},"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-s2b4/_output_.zip') as myzip:\n    with myzip.open('S2B4_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-16T14:55:04.865498Z","iopub.execute_input":"2025-12-16T14:55:04.865835Z","iopub.status.idle":"2025-12-16T14:55:08.140991Z","shell.execute_reply.started":"2025-12-16T14:55:04.865810Z","shell.execute_reply":"2025-12-16T14:55:08.139959Z"}},"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-16T14:56:23.443211Z","iopub.execute_input":"2025-12-16T14:56:23.443594Z","iopub.status.idle":"2025-12-16T14:56:23.458754Z","shell.execute_reply.started":"2025-12-16T14:56:23.443570Z","shell.execute_reply":"2025-12-16T14:56:23.457537Z"}},"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-16T14:56:23.899453Z","iopub.execute_input":"2025-12-16T14:56:23.899810Z","iopub.status.idle":"2025-12-16T14:56:23.912489Z","shell.execute_reply.started":"2025-12-16T14:56:23.899782Z","shell.execute_reply":"2025-12-16T14:56:23.911222Z"}},"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-16T14:56:25.646574Z","iopub.execute_input":"2025-12-16T14:56:25.646934Z","iopub.status.idle":"2025-12-16T14:56:25.823255Z","shell.execute_reply.started":"2025-12-16T14:56:25.646909Z","shell.execute_reply":"2025-12-16T14:56:25.822207Z"}},"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-16T14:56:27.096934Z","iopub.execute_input":"2025-12-16T14:56:27.098255Z","iopub.status.idle":"2025-12-16T14:56:27.104926Z","shell.execute_reply.started":"2025-12-16T14:56:27.098221Z","shell.execute_reply":"2025-12-16T14:56:27.103736Z"}},"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-16T14:56:51.202413Z","iopub.execute_input":"2025-12-16T14:56:51.202776Z","iopub.status.idle":"2025-12-16T14:56:51.269261Z","shell.execute_reply.started":"2025-12-16T14:56:51.202744Z","shell.execute_reply":"2025-12-16T14:56:51.268354Z"},"_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-16T14:56:51.548755Z","iopub.execute_input":"2025-12-16T14:56:51.549130Z","iopub.status.idle":"2025-12-16T14:56:53.162600Z","shell.execute_reply.started":"2025-12-16T14:56:51.549077Z","shell.execute_reply":"2025-12-16T14:56:53.161453Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# SAMPLE_SIZE = 1000","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-16T14:56:53.164069Z","iopub.execute_input":"2025-12-16T14:56:53.164448Z","iopub.status.idle":"2025-12-16T14:56:53.169278Z","shell.execute_reply.started":"2025-12-16T14:56:53.164417Z","shell.execute_reply":"2025-12-16T14:56:53.168143Z"}},"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-16T14:56:57.425236Z","iopub.execute_input":"2025-12-16T14:56:57.425582Z","iopub.status.idle":"2025-12-16T14:56:57.451317Z","shell.execute_reply.started":"2025-12-16T14:56:57.425559Z","shell.execute_reply":"2025-12-16T14:56:57.450160Z"}},"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-16T14:56:57.692685Z","iopub.execute_input":"2025-12-16T14:56:57.693135Z","iopub.status.idle":"2025-12-16T14:56:58.003731Z","shell.execute_reply.started":"2025-12-16T14:56:57.693081Z","shell.execute_reply":"2025-12-16T14:56:58.002363Z"}},"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-16T14:56:58.005576Z","iopub.execute_input":"2025-12-16T14:56:58.005967Z","iopub.status.idle":"2025-12-16T14:57:08.647034Z","shell.execute_reply.started":"2025-12-16T14:56:58.005924Z","shell.execute_reply":"2025-12-16T14:57:08.645620Z"}},"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-16T14:57:08.649074Z","iopub.execute_input":"2025-12-16T14:57:08.649536Z","iopub.status.idle":"2025-12-16T14:57:20.418961Z","shell.execute_reply.started":"2025-12-16T14:57:08.649486Z","shell.execute_reply":"2025-12-16T14:57:20.417437Z"}},"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-16T14:57:20.420075Z","iopub.execute_input":"2025-12-16T14:57:20.420447Z","iopub.status.idle":"2025-12-16T14:57:32.325466Z","shell.execute_reply.started":"2025-12-16T14:57:20.420426Z","shell.execute_reply":"2025-12-16T14:57:32.323954Z"}},"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-16T14:57:32.327197Z","iopub.execute_input":"2025-12-16T14:57:32.327962Z","iopub.status.idle":"2025-12-16T14:57:42.900148Z","shell.execute_reply.started":"2025-12-16T14:57:32.327936Z","shell.execute_reply":"2025-12-16T14:57:42.898773Z"}},"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-16T14:57:48.795028Z","iopub.execute_input":"2025-12-16T14:57:48.796332Z","iopub.status.idle":"2025-12-16T14:57:48.851713Z","shell.execute_reply.started":"2025-12-16T14:57:48.796301Z","shell.execute_reply":"2025-12-16T14:57:48.850669Z"}},"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}]}