{"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,"sourceType":"competition"},{"sourceId":287964374,"sourceType":"kernelVersion"}],"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"* Conv2dRBFv2にする","metadata":{}},{"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-25T13:17:06.836627Z","iopub.execute_input":"2025-12-25T13:17:06.836943Z","iopub.status.idle":"2025-12-25T13:18:23.097320Z","shell.execute_reply.started":"2025-12-25T13:17:06.836910Z","shell.execute_reply":"2025-12-25T13:18:23.096360Z"},"_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-25T13:18:23.098742Z","iopub.execute_input":"2025-12-25T13:18:23.099010Z","iopub.status.idle":"2025-12-25T13:18:42.233050Z","shell.execute_reply.started":"2025-12-25T13:18:23.098972Z","shell.execute_reply":"2025-12-25T13:18:42.231461Z"},"_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-25T13:18:42.234084Z","iopub.execute_input":"2025-12-25T13:18:42.234309Z","iopub.status.idle":"2025-12-25T13:18:50.980884Z","shell.execute_reply.started":"2025-12-25T13:18:42.234289Z","shell.execute_reply":"2025-12-25T13:18:50.979627Z"}},"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-25T13:18:50.983324Z","iopub.execute_input":"2025-12-25T13:18:50.983878Z","iopub.status.idle":"2025-12-25T13:18:50.991239Z","shell.execute_reply.started":"2025-12-25T13:18:50.983860Z","shell.execute_reply":"2025-12-25T13:18:50.990129Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# ! pip install libarchive-c","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:18:50.992490Z","iopub.execute_input":"2025-12-25T13:18:50.992864Z","iopub.status.idle":"2025-12-25T13:18:51.591160Z","shell.execute_reply.started":"2025-12-25T13:18:50.992842Z","shell.execute_reply":"2025-12-25T13:18:51.590518Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"! pip install py7zr","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:18:51.592675Z","iopub.execute_input":"2025-12-25T13:18:51.593757Z","iopub.status.idle":"2025-12-25T13:19:15.277639Z","shell.execute_reply.started":"2025-12-25T13:18:51.593713Z","shell.execute_reply":"2025-12-25T13:19:15.276770Z"},"_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-25T13:19:15.278601Z","iopub.execute_input":"2025-12-25T13:19:15.278812Z","iopub.status.idle":"2025-12-25T13:19:15.365363Z","shell.execute_reply.started":"2025-12-25T13:19:15.278793Z","shell.execute_reply":"2025-12-25T13:19:15.363933Z"}},"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-25T13:19:15.366889Z","iopub.execute_input":"2025-12-25T13:19:15.367246Z","iopub.status.idle":"2025-12-25T13:19:35.264458Z","shell.execute_reply.started":"2025-12-25T13:19:15.367225Z","shell.execute_reply":"2025-12-25T13:19:35.263602Z"}},"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-25T13:19:35.265253Z","iopub.execute_input":"2025-12-25T13:19:35.265746Z","iopub.status.idle":"2025-12-25T13:19:43.725742Z","shell.execute_reply.started":"2025-12-25T13:19:35.265730Z","shell.execute_reply":"2025-12-25T13:19:43.724285Z"},"_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-25T13:19:43.728713Z","iopub.execute_input":"2025-12-25T13:19:43.728937Z","iopub.status.idle":"2025-12-25T13:19:43.826675Z","shell.execute_reply.started":"2025-12-25T13:19:43.728917Z","shell.execute_reply":"2025-12-25T13:19:43.825781Z"}},"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-25T13:19:43.827340Z","iopub.execute_input":"2025-12-25T13:19:43.827893Z","iopub.status.idle":"2025-12-25T13:19:43.833056Z","shell.execute_reply.started":"2025-12-25T13:19:43.827877Z","shell.execute_reply":"2025-12-25T13:19:43.831937Z"}},"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-25T13:19:43.833883Z","iopub.execute_input":"2025-12-25T13:19:43.834180Z","iopub.status.idle":"2025-12-25T13:19:43.852978Z","shell.execute_reply.started":"2025-12-25T13:19:43.834160Z","shell.execute_reply":"2025-12-25T13:19:43.852361Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"! mkdir img","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:19:43.853976Z","iopub.execute_input":"2025-12-25T13:19:43.854163Z","iopub.status.idle":"2025-12-25T13:19:44.008140Z","shell.execute_reply.started":"2025-12-25T13:19:43.854145Z","shell.execute_reply":"2025-12-25T13:19:44.007361Z"}},"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-25T13:19:44.008936Z","iopub.execute_input":"2025-12-25T13:19:44.009175Z","iopub.status.idle":"2025-12-25T13:19:44.015620Z","shell.execute_reply.started":"2025-12-25T13:19:44.009102Z","shell.execute_reply":"2025-12-25T13:19:44.014470Z"}},"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-25T13:19:44.016606Z","iopub.execute_input":"2025-12-25T13:19:44.016854Z","iopub.status.idle":"2025-12-25T13:19:44.037428Z","shell.execute_reply.started":"2025-12-25T13:19:44.016837Z","shell.execute_reply":"2025-12-25T13:19:44.036222Z"}},"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-25T13:19:44.038726Z","iopub.execute_input":"2025-12-25T13:19:44.039096Z","iopub.status.idle":"2025-12-25T13:20:02.535279Z","shell.execute_reply.started":"2025-12-25T13:19:44.039062Z","shell.execute_reply":"2025-12-25T13:20:02.534355Z"}},"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-25T13:20:02.536423Z","iopub.execute_input":"2025-12-25T13:20:02.536649Z","iopub.status.idle":"2025-12-25T13:20:02.585253Z","shell.execute_reply.started":"2025-12-25T13:20:02.536629Z","shell.execute_reply":"2025-12-25T13:20:02.584473Z"}},"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-25T13:20:02.586388Z","iopub.execute_input":"2025-12-25T13:20:02.586634Z","iopub.status.idle":"2025-12-25T13:20:08.574860Z","shell.execute_reply.started":"2025-12-25T13:20:02.586613Z","shell.execute_reply":"2025-12-25T13:20:08.573973Z"}},"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-25T13:20:08.575916Z","iopub.execute_input":"2025-12-25T13:20:08.576190Z","iopub.status.idle":"2025-12-25T13:20:08.903719Z","shell.execute_reply.started":"2025-12-25T13:20:08.576168Z","shell.execute_reply":"2025-12-25T13:20:08.902169Z"}},"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-25T13:20:08.905236Z","iopub.execute_input":"2025-12-25T13:20:08.905543Z","iopub.status.idle":"2025-12-25T13:20:08.912916Z","shell.execute_reply.started":"2025-12-25T13:20:08.905519Z","shell.execute_reply":"2025-12-25T13:20:08.911862Z"}},"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-25T13:20:08.914074Z","iopub.execute_input":"2025-12-25T13:20:08.914741Z","iopub.status.idle":"2025-12-25T13:20:09.630076Z","shell.execute_reply.started":"2025-12-25T13:20:08.914719Z","shell.execute_reply":"2025-12-25T13:20:09.629085Z"}},"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-25T13:20:09.630736Z","iopub.execute_input":"2025-12-25T13:20:09.630917Z","iopub.status.idle":"2025-12-25T13:22:02.855144Z","shell.execute_reply.started":"2025-12-25T13:20:09.630897Z","shell.execute_reply":"2025-12-25T13:22:02.854394Z"}},"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-25T13:22:02.855844Z","iopub.execute_input":"2025-12-25T13:22:02.856017Z","iopub.status.idle":"2025-12-25T13:22:03.196990Z","shell.execute_reply.started":"2025-12-25T13:22:02.856003Z","shell.execute_reply":"2025-12-25T13:22:03.195926Z"}},"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-25T13:22:03.197944Z","iopub.execute_input":"2025-12-25T13:22:03.198164Z","iopub.status.idle":"2025-12-25T13:22:38.526038Z","shell.execute_reply.started":"2025-12-25T13:22:03.198145Z","shell.execute_reply":"2025-12-25T13:22:38.524603Z"}},"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-25T13:22:38.527246Z","iopub.execute_input":"2025-12-25T13:22:38.527539Z","iopub.status.idle":"2025-12-25T13:22:40.616943Z","shell.execute_reply.started":"2025-12-25T13:22:38.527519Z","shell.execute_reply":"2025-12-25T13:22:40.616168Z"}},"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-25T13:22:40.617808Z","iopub.execute_input":"2025-12-25T13:22:40.618084Z","iopub.status.idle":"2025-12-25T13:22:40.699347Z","shell.execute_reply.started":"2025-12-25T13:22:40.618066Z","shell.execute_reply":"2025-12-25T13:22:40.698542Z"}},"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-25T13:22:40.700058Z","iopub.execute_input":"2025-12-25T13:22:40.700260Z","iopub.status.idle":"2025-12-25T13:22:40.722000Z","shell.execute_reply.started":"2025-12-25T13:22:40.700244Z","shell.execute_reply":"2025-12-25T13:22:40.721373Z"}},"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-25T13:22:40.725908Z","iopub.execute_input":"2025-12-25T13:22:40.726084Z","iopub.status.idle":"2025-12-25T13:22:40.760365Z","shell.execute_reply.started":"2025-12-25T13:22:40.726067Z","shell.execute_reply":"2025-12-25T13:22:40.759526Z"}},"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-25T13:22:40.761173Z","iopub.execute_input":"2025-12-25T13:22:40.761434Z","iopub.status.idle":"2025-12-25T13:22:40.780712Z","shell.execute_reply.started":"2025-12-25T13:22:40.761411Z","shell.execute_reply":"2025-12-25T13:22:40.780104Z"}},"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-25T13:22:40.781384Z","iopub.execute_input":"2025-12-25T13:22:40.781611Z","iopub.status.idle":"2025-12-25T13:22:40.802673Z","shell.execute_reply.started":"2025-12-25T13:22:40.781589Z","shell.execute_reply":"2025-12-25T13:22:40.801882Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"np.unique(y_labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:22:40.803658Z","iopub.execute_input":"2025-12-25T13:22:40.804004Z","iopub.status.idle":"2025-12-25T13:22:40.824910Z","shell.execute_reply.started":"2025-12-25T13:22:40.803981Z","shell.execute_reply":"2025-12-25T13:22:40.823970Z"}},"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-25T13:22:40.825865Z","iopub.execute_input":"2025-12-25T13:22:40.826105Z","iopub.status.idle":"2025-12-25T13:22:40.921698Z","shell.execute_reply.started":"2025-12-25T13:22:40.826084Z","shell.execute_reply":"2025-12-25T13:22:40.920719Z"}},"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-25T13:22:40.922485Z","iopub.execute_input":"2025-12-25T13:22:40.922659Z","iopub.status.idle":"2025-12-25T13:22:40.962910Z","shell.execute_reply.started":"2025-12-25T13:22:40.922645Z","shell.execute_reply":"2025-12-25T13:22:40.962227Z"}},"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-25T13:22:40.963661Z","iopub.execute_input":"2025-12-25T13:22:40.963879Z","iopub.status.idle":"2025-12-25T13:22:41.046245Z","shell.execute_reply.started":"2025-12-25T13:22:40.963861Z","shell.execute_reply":"2025-12-25T13:22:41.045225Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.imshow(img_array)\nsave_img()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:22:41.046980Z","iopub.execute_input":"2025-12-25T13:22:41.047233Z","iopub.status.idle":"2025-12-25T13:22:41.246857Z","shell.execute_reply.started":"2025-12-25T13:22:41.047217Z","shell.execute_reply":"2025-12-25T13:22:41.245505Z"}},"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-25T13:22:41.247953Z","iopub.execute_input":"2025-12-25T13:22:41.248241Z","iopub.status.idle":"2025-12-25T13:22:41.267934Z","shell.execute_reply.started":"2025-12-25T13:22:41.248221Z","shell.execute_reply":"2025-12-25T13:22:41.266964Z"}},"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-25T13:22:41.269026Z","iopub.execute_input":"2025-12-25T13:22:41.269310Z","iopub.status.idle":"2025-12-25T13:22:41.274308Z","shell.execute_reply.started":"2025-12-25T13:22:41.269294Z","shell.execute_reply":"2025-12-25T13:22:41.273434Z"}},"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-25T13:22:41.275188Z","iopub.execute_input":"2025-12-25T13:22:41.275896Z","iopub.status.idle":"2025-12-25T13:22:41.292838Z","shell.execute_reply.started":"2025-12-25T13:22:41.275879Z","shell.execute_reply":"2025-12-25T13:22:41.291852Z"}},"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-25T13:22:41.293877Z","iopub.execute_input":"2025-12-25T13:22:41.294266Z","iopub.status.idle":"2025-12-25T13:22:41.310924Z","shell.execute_reply.started":"2025-12-25T13:22:41.294242Z","shell.execute_reply":"2025-12-25T13:22:41.309631Z"}},"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-25T13:22:41.312010Z","iopub.execute_input":"2025-12-25T13:22:41.312362Z","iopub.status.idle":"2025-12-25T13:22:41.338462Z","shell.execute_reply.started":"2025-12-25T13:22:41.312334Z","shell.execute_reply":"2025-12-25T13:22:41.337507Z"}},"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-25T13:22:41.339487Z","iopub.execute_input":"2025-12-25T13:22:41.339793Z","iopub.status.idle":"2025-12-25T13:22:48.586875Z","shell.execute_reply.started":"2025-12-25T13:22:41.339773Z","shell.execute_reply":"2025-12-25T13:22:48.585775Z"}},"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-25T13:22:48.587650Z","iopub.execute_input":"2025-12-25T13:22:48.587860Z","iopub.status.idle":"2025-12-25T13:22:56.960717Z","shell.execute_reply.started":"2025-12-25T13:22:48.587842Z","shell.execute_reply":"2025-12-25T13:22:56.959719Z"}},"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-25T13:22:56.961796Z","iopub.execute_input":"2025-12-25T13:22:56.962001Z","iopub.status.idle":"2025-12-25T13:23:06.920515Z","shell.execute_reply.started":"2025-12-25T13:22:56.961987Z","shell.execute_reply":"2025-12-25T13:23:06.919438Z"}},"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-25T13:23:06.921992Z","iopub.execute_input":"2025-12-25T13:23:06.922309Z","iopub.status.idle":"2025-12-25T13:23:14.150560Z","shell.execute_reply.started":"2025-12-25T13:23:06.922288Z","shell.execute_reply":"2025-12-25T13:23:14.149301Z"}},"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-25T13:23:14.151647Z","iopub.execute_input":"2025-12-25T13:23:14.151916Z","iopub.status.idle":"2025-12-25T13:23:14.157618Z","shell.execute_reply.started":"2025-12-25T13:23:14.151895Z","shell.execute_reply":"2025-12-25T13:23:14.156495Z"}},"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.layers import Layer\nfrom tensorflow.keras import initializers, constraints\nfrom tensorflow.keras import regularizers\nimport tensorflow.keras.backend as K","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:23:14.158874Z","iopub.execute_input":"2025-12-25T13:23:14.159182Z","iopub.status.idle":"2025-12-25T13:23:14.184649Z","shell.execute_reply.started":"2025-12-25T13:23:14.159156Z","shell.execute_reply":"2025-12-25T13:23:14.183207Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# rl = 0.001\n# rl = 0.002\nrl = 0.005\n# rl = 0.008\nrbf_target = 0.5\nnum_epoch = 64\n# num_epoch = 256 * 2\nstructure = 'S2B3'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:23:14.186757Z","iopub.execute_input":"2025-12-25T13:23:14.187077Z","iopub.status.idle":"2025-12-25T13:23:14.207579Z","shell.execute_reply.started":"2025-12-25T13:23:14.187060Z","shell.execute_reply":"2025-12-25T13:23:14.206168Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Conv2DRBFv2","metadata":{}},{"cell_type":"code","source":"class Conv2DRBFv2(Layer):\n    \"\"\"\n    RBFカーネル畳み込みレイヤー (Conv2D-RBF) - フィルタ個別gamma版\n\n    通常のConv2D層の積和演算（内積）を RBF カーネル（非線形類似度）に置き換えます。\n    各フィルタ（出力チャンネル）ごとに独立した gamma パラメータを持ち、\n    それぞれのランドマークに適した射程距離を個別に学習します。\n    \"\"\"\n    def __init__(self, filters, kernel_size,\n                 gamma_initializer=initializers.Constant(np.log(1 / (0.2**2))),\n                 kernel_initializer=initializers.RandomUniform(minval=0.0, maxval=1.0),\n                 strides=(1, 1), padding='valid', **kwargs):\n        \n        super(Conv2DRBFv2, self).__init__(**kwargs)\n        \n        self.filters = filters\n        self.kernel_size = tuple(kernel_size)\n        self.strides = tuple(strides)\n        self.padding = padding.upper() \n        \n        self.gamma_initializer = initializers.get(gamma_initializer)\n        self.gamma_constraint = None \n\n        self.kernel_initializer = kernel_initializer\n\n    def build(self, input_shape):\n        input_dim = input_shape[-1]\n        \n        # 1. ランドマーク (カーネル μ) の定義: (kH, kW, C_in, F)\n        self.kernel = self.add_weight(\n            shape=self.kernel_size + (input_dim, self.filters),\n            initializer=self.kernel_initializer,\n            name='rbf_kernel_landmarks',\n            trainable=True,\n        )\n\n        # 2. フィルタごとの log_gamma の定義\n        # shape を (self.filters,) に設定することで、各フィルタ固有の値を保持\n        self.log_gamma = self.add_weight(\n            shape=(self.filters,),\n            initializer=self.gamma_initializer,\n            name='log_gamma',\n            trainable=True\n        )\n        \n        super(Conv2DRBFv2, self).build(input_shape)\n\n    def call(self, inputs):\n        gamma = tf.exp(self.log_gamma)\n        gamma_reshaped = tf.reshape(gamma, (1, 1, 1, self.filters))\n\n        # 1. パッチ抽出 (B, H, W, 27)\n        patches = tf.image.extract_patches(\n            images=inputs,\n            sizes=[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            padding=self.padding\n        )\n\n        # 2. フィルタの平坦化 (27, 16) \n        # フィルタ次元(F)を最後に維持すれば、reshapeだけで各フィルタの重みが正しく並ぶ\n        C_flat = self.kernel_size[0] * self.kernel_size[1] * tf.shape(inputs)[-1]\n        kernel_flat = tf.reshape(self.kernel, (C_flat, self.filters))\n\n        # 3. 距離計算の構成要素\n        # パッチのノルム二乗: (B, H, W, 1)\n        patch_norm_sq = tf.reduce_sum(tf.square(patches), axis=-1, keepdims=True)\n\n        # ランドマークのノルム二乗: (1, 1, 1, 16)\n        # 修正：kernel_flat (27, 16) の縦方向に和をとる\n        kernel_norm_sq = tf.reduce_sum(tf.square(kernel_flat), axis=0)\n        kernel_norm_sq = tf.reshape(kernel_norm_sq, (1, 1, 1, self.filters))\n\n        # 内積: (B, H, W, 16)\n        # patches(B,H,W,27) と kernel_flat(27,16) の行列積\n        inner_product = tf.matmul(patches, kernel_flat)\n        \n        # 4. 合体\n        sq_dist = patch_norm_sq + kernel_norm_sq - 2.0 * inner_product\n        rbf_output = tf.exp(-gamma_reshaped * sq_dist)\n\n        return rbf_output\n    def compute_output_shape(self, input_shape):\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        else: # 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            \n        return (input_shape[0], H_out, W_out, self.filters)\n\n    def get_config(self):\n        config = super(Conv2DRBFv2, 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            'kernel_initializer': initializers.serialize(self.kernel_initializer),\n        })\n        return config","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:43:15.985158Z","iopub.execute_input":"2025-12-25T13:43:15.985440Z","iopub.status.idle":"2025-12-25T13:43:16.001806Z","shell.execute_reply.started":"2025-12-25T13:43:15.985425Z","shell.execute_reply":"2025-12-25T13:43:16.000671Z"}},"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 = Conv2DRBFv2(\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-25T13:43:17.791302Z","iopub.execute_input":"2025-12-25T13:43:17.791588Z","iopub.status.idle":"2025-12-25T13:43:17.830735Z","shell.execute_reply.started":"2025-12-25T13:43:17.791573Z","shell.execute_reply":"2025-12-25T13:43:17.829923Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"hybrid_model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['categorical_accuracy'])\nhybrid_model.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:43:18.088566Z","iopub.execute_input":"2025-12-25T13:43:18.088827Z","iopub.status.idle":"2025-12-25T13:43:18.116667Z","shell.execute_reply.started":"2025-12-25T13:43:18.088813Z","shell.execute_reply":"2025-12-25T13:43:18.115906Z"}},"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-25T13:43:19.558453Z","iopub.execute_input":"2025-12-25T13:43:19.558766Z","iopub.status.idle":"2025-12-25T13:43:19.641488Z","shell.execute_reply.started":"2025-12-25T13:43:19.558744Z","shell.execute_reply":"2025-12-25T13:43:19.640636Z"}},"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-25T13:43:20.425337Z","iopub.execute_input":"2025-12-25T13:43:20.426505Z","iopub.status.idle":"2025-12-25T13:43:20.566997Z","shell.execute_reply.started":"2025-12-25T13:43:20.426447Z","shell.execute_reply":"2025-12-25T13:43:20.565732Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pred[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:43:20.665463Z","iopub.execute_input":"2025-12-25T13:43:20.666444Z","iopub.status.idle":"2025-12-25T13:43:20.671581Z","shell.execute_reply.started":"2025-12-25T13:43:20.666419Z","shell.execute_reply":"2025-12-25T13:43:20.670811Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"hybrid_model.layers","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:43:20.956272Z","iopub.execute_input":"2025-12-25T13:43:20.956533Z","iopub.status.idle":"2025-12-25T13:43:20.963411Z","shell.execute_reply.started":"2025-12-25T13:43:20.956519Z","shell.execute_reply":"2025-12-25T13:43:20.962269Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"hybrid_model.layers[1].output","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:43:21.177241Z","iopub.execute_input":"2025-12-25T13:43:21.177537Z","iopub.status.idle":"2025-12-25T13:43:21.183279Z","shell.execute_reply.started":"2025-12-25T13:43:21.177517Z","shell.execute_reply":"2025-12-25T13:43:21.181766Z"}},"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-25T13:43:22.347838Z","iopub.execute_input":"2025-12-25T13:43:22.348162Z","iopub.status.idle":"2025-12-25T13:43:22.366034Z","shell.execute_reply.started":"2025-12-25T13:43:22.348141Z","shell.execute_reply":"2025-12-25T13:43:22.365180Z"}},"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-25T13:43:22.600926Z","iopub.execute_input":"2025-12-25T13:43:22.601250Z","iopub.status.idle":"2025-12-25T13:43:22.648272Z","shell.execute_reply.started":"2025-12-25T13:43:22.601231Z","shell.execute_reply":"2025-12-25T13:43:22.646991Z"}},"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-25T13:43:23.761840Z","iopub.execute_input":"2025-12-25T13:43:23.762228Z","iopub.status.idle":"2025-12-25T13:43:23.768292Z","shell.execute_reply.started":"2025-12-25T13:43:23.762203Z","shell.execute_reply":"2025-12-25T13:43:23.767609Z"}},"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-25T13:43:24.031784Z","iopub.execute_input":"2025-12-25T13:43:24.032764Z","iopub.status.idle":"2025-12-25T13:43:24.036497Z","shell.execute_reply.started":"2025-12-25T13:43:24.032739Z","shell.execute_reply":"2025-12-25T13:43:24.035858Z"}},"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-25T13:43:24.260624Z","iopub.execute_input":"2025-12-25T13:43:24.261172Z","iopub.status.idle":"2025-12-25T13:43:24.271454Z","shell.execute_reply.started":"2025-12-25T13:43:24.261149Z","shell.execute_reply":"2025-12-25T13:43:24.270017Z"}},"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-25T13:43:25.468996Z","iopub.execute_input":"2025-12-25T13:43:25.469373Z","iopub.status.idle":"2025-12-25T13:43:25.477661Z","shell.execute_reply.started":"2025-12-25T13:43:25.469354Z","shell.execute_reply":"2025-12-25T13:43:25.476622Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"filters.reshape(-1, filters.shape[-1]).shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:43:25.759883Z","iopub.execute_input":"2025-12-25T13:43:25.760260Z","iopub.status.idle":"2025-12-25T13:43:25.767878Z","shell.execute_reply.started":"2025-12-25T13:43:25.760240Z","shell.execute_reply":"2025-12-25T13:43:25.766803Z"}},"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-25T13:43:26.433214Z","iopub.execute_input":"2025-12-25T13:43:26.433520Z","iopub.status.idle":"2025-12-25T13:43:28.348526Z","shell.execute_reply.started":"2025-12-25T13:43:26.433501Z","shell.execute_reply":"2025-12-25T13:43:28.347482Z"}},"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-25T13:43:28.350290Z","iopub.execute_input":"2025-12-25T13:43:28.350922Z","iopub.status.idle":"2025-12-25T13:43:30.274070Z","shell.execute_reply.started":"2025-12-25T13:43:28.350897Z","shell.execute_reply":"2025-12-25T13:43:30.273259Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Conv2dRBFのResNetを構築","metadata":{}},{"cell_type":"code","source":"def Hybrid_resnet_layer_Conv2DRBF(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 = Conv2DRBFv2(\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-25T13:43:30.275050Z","iopub.execute_input":"2025-12-25T13:43:30.275243Z","iopub.status.idle":"2025-12-25T13:43:30.283698Z","shell.execute_reply.started":"2025-12-25T13:43:30.275229Z","shell.execute_reply":"2025-12-25T13:43:30.282509Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"### Hybrid_resnet_layer test\ninp = Input(shape=(8, 8, 32))\noup = Hybrid_resnet_layer_Conv2DRBF(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-25T13:43:31.068405Z","iopub.execute_input":"2025-12-25T13:43:31.068669Z","iopub.status.idle":"2025-12-25T13:43:31.095482Z","shell.execute_reply.started":"2025-12-25T13:43:31.068654Z","shell.execute_reply":"2025-12-25T13:43:31.094663Z"}},"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-25T13:43:32.639768Z","iopub.execute_input":"2025-12-25T13:43:32.640556Z","iopub.status.idle":"2025-12-25T13:43:32.692735Z","shell.execute_reply.started":"2025-12-25T13:43:32.640534Z","shell.execute_reply":"2025-12-25T13:43:32.691766Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## ResNet20_Cconv2d_RBF","metadata":{}},{"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-25T13:43:33.808330Z","iopub.execute_input":"2025-12-25T13:43:33.808592Z","iopub.status.idle":"2025-12-25T13:43:33.815279Z","shell.execute_reply.started":"2025-12-25T13:43:33.808576Z","shell.execute_reply":"2025-12-25T13:43:33.814028Z"}},"outputs":[],"execution_count":null},{"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_Conv2DRBF(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_Conv2DRBF(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_Conv2DRBF(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_Conv2DRBF(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_Conv2DRBF(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-25T13:43:35.206188Z","iopub.execute_input":"2025-12-25T13:43:35.206558Z","iopub.status.idle":"2025-12-25T13:43:35.221588Z","shell.execute_reply.started":"2025-12-25T13:43:35.206534Z","shell.execute_reply":"2025-12-25T13:43:35.220712Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# --- モデルのインスタンス化と確認 ---\nmodel_Conv2dRBF = ResNet20_C_RBF_Hybrid(input_shape=(32, 32, 3), num_stages=2, depth=29, num_classes=10, activation='relu')\nmodel_Conv2dRBF.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:43:38.410487Z","iopub.execute_input":"2025-12-25T13:43:38.411569Z","iopub.status.idle":"2025-12-25T13:43:38.534305Z","shell.execute_reply.started":"2025-12-25T13:43:38.411547Z","shell.execute_reply":"2025-12-25T13:43:38.533071Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_model(model_Conv2dRBF, show_shapes=True, expand_nested=True, show_layer_names=True, dpi=70)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:43:41.488961Z","iopub.execute_input":"2025-12-25T13:43:41.490028Z","iopub.status.idle":"2025-12-25T13:43:41.672330Z","shell.execute_reply.started":"2025-12-25T13:43:41.490004Z","shell.execute_reply":"2025-12-25T13:43:41.671353Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## adjust_rbf_weights_v2","metadata":{}},{"cell_type":"code","source":"def adjust_rbf_weights_v2(model, x_sample, rbf_target=0.5, mode='avg', bins=19, rbf_target_name='rbf_conv2d'):\n    \"\"\"\n    RBF層の出力統計量が rbf_target になるように gamma を自動調整する。\n    \n    Args:\n        model: 対象のKerasモデル\n        x_sample: 統計計算用のサンプルデータ (例: x_train[:1000])\n        rbf_target: 統計量として目指すRBF出力値 (デフォルト: 0.5)\n        mode: 'avg' (平均), 'median' (中央値), 'mode' (最頻値)\n        bins: mode='mode' の場合のヒストグラム分割数\n    \"\"\"\n    print(f\"--- Adjusting RBF weights (target: {rbf_target}, mode: {mode}) ---\")\n    \n    # モデル内のConv2dRBF層（またはRBF層）を抽出\n    # 層の名前やクラス名でフィルタリングしてください\n    rbf_layers = [l for l in model.layers if rbf_target_name in l.name.lower()]\n    print(rbf_layers)\n    \n    if not rbf_layers:\n        print(\"No RBF layers found.\")\n        return\n    for i, layer in enumerate(rbf_layers):\n        print(layer.name)\n        # 中間出力を取得するためのサブモデルを作成\n        intermediate_model = tf.keras.Model(inputs=model.input, outputs=layer.output)\n        \n        # RBF層の出力を計算 (ガウス関数適用後の 0~1 の値)\n        # 構造によっては、RBF計算直前の「距離」が必要な場合がありますが、\n        # ここでは「現在の出力」から逆算するロジックとします。\n        out = intermediate_model.predict(x_sample, verbose=0)\n        print('out.shape >>>', out.shape)\n        \n        # 統計量の算出\n        # ここはフィルターごとに算出する\n        if mode == 'avg':\n            current_val = np.mean(out, axis=(0,1,2))\n        elif mode == 'median':\n            current_val = np.median(out, axis=(0,1,2))\n        elif mode == 'mode':\n            #counts, bin_edges = np.histogram(out, bins=bins)\n            tmp = [np.histogram(out[ii], bins=bins) for ii in range(out.shape[-1])]\n            #current_val = bin_edges[np.argmax(counts) + 1] # 頻度最大のbinの中央付近\n            list_current_val = [bin_edges[np.argmax(counts) + 1] for counts, bin_edges in tmp]\n            current_val = np.array(list_current_val)\n        print('current_val.shape >>>', current_val.shape)\n        \n        # # 1.0 または 0.0 への張り付きを回避するための安全策\n        current_val = np.clip(current_val, 1e-7, 1.0 - 1e-7)\n        print(f'current_val : {mode} - {current_val}')\n        \n        # ガウス関数 y = exp(-gamma * d^2) の逆算\n        # log(y) = -gamma * d^2  =>  d^2 = -log(y) / gamma_old\n        # 新しい gamma_new = -log(target) / d^2\n        # => gamma_new = gamma_old * (log(target) / log(current_val))\n        \n        weights = layer.get_weights()\n        # 重みの並びが [kernel, gamma] または [gamma] の場合を想定\n        # ※層の実装に合わせてインデックスを調整してください\n        gamma_index = -1 \n        old_gamma = np.exp(weights[gamma_index])\n        print('old_gamma.shape >>>', old_gamma.shape)\n        \n        # 新しいgammaの計算\n        gamma_adjustment = np.log(rbf_target) / np.log(current_val)\n        print('gamma_adjustment.shape >>>', gamma_adjustment.shape)\n        new_gamma = old_gamma * gamma_adjustment\n        print('new_gamma.shape >>>', new_gamma.shape)\n        \n        # 重みの更新\n        weights[gamma_index] = np.log(new_gamma)\n        layer.set_weights(weights)\n        \n        print(f\"Layer {i} ({layer.name}): {mode}={current_val[0]:.4f} -> target {rbf_target}. Gamma updated. {old_gamma[0]} -> {new_gamma[0]}\")\n\n    print(\"--- Adjustment completed ---\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:43:47.502958Z","iopub.execute_input":"2025-12-25T13:43:47.504020Z","iopub.status.idle":"2025-12-25T13:43:47.515353Z","shell.execute_reply.started":"2025-12-25T13:43:47.503998Z","shell.execute_reply":"2025-12-25T13:43:47.513874Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"SAMPLE_SIZE = 10000\nadjust_rbf_weights_v2(model_Conv2dRBF, x_train[:SAMPLE_SIZE], rbf_target=rbf_target, mode='median', bins=19)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:43:49.474070Z","iopub.execute_input":"2025-12-25T13:43:49.475383Z","iopub.status.idle":"2025-12-25T13:44:10.145993Z","shell.execute_reply.started":"2025-12-25T13:43:49.475321Z","shell.execute_reply":"2025-12-25T13:44:10.144046Z"},"_kg_hide-output":true},"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} に保存しました。\")\n\n# save_custom_weights(model_baseline, file_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:44:10.147602Z","iopub.execute_input":"2025-12-25T13:44:10.147812Z","iopub.status.idle":"2025-12-25T13:44:10.154182Z","shell.execute_reply.started":"2025-12-25T13:44:10.147797Z","shell.execute_reply":"2025-12-25T13:44:10.153190Z"}},"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-25T13:44:10.155382Z","iopub.execute_input":"2025-12-25T13:44:10.155670Z","iopub.status.idle":"2025-12-25T13:44:10.180820Z","shell.execute_reply.started":"2025-12-25T13:44:10.155649Z","shell.execute_reply":"2025-12-25T13:44:10.179612Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## model_test2","metadata":{}},{"cell_type":"code","source":"model_test = Model(inputs=model_Conv2dRBF.input, outputs=model_Conv2dRBF.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-25T13:44:10.183555Z","iopub.execute_input":"2025-12-25T13:44:10.183919Z","iopub.status.idle":"2025-12-25T13:44:10.227270Z","shell.execute_reply.started":"2025-12-25T13:44:10.183900Z","shell.execute_reply":"2025-12-25T13:44:10.225833Z"}},"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-25T13:44:10.228422Z","iopub.execute_input":"2025-12-25T13:44:10.228694Z","iopub.status.idle":"2025-12-25T13:44:10.424501Z","shell.execute_reply.started":"2025-12-25T13:44:10.228668Z","shell.execute_reply":"2025-12-25T13:44:10.423063Z"}},"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-25T13:44:10.426184Z","iopub.execute_input":"2025-12-25T13:44:10.426634Z","iopub.status.idle":"2025-12-25T13:44:18.693346Z","shell.execute_reply.started":"2025-12-25T13:44:10.426595Z","shell.execute_reply":"2025-12-25T13:44:18.692419Z"}},"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-25T13:44:18.694395Z","iopub.execute_input":"2025-12-25T13:44:18.694618Z","iopub.status.idle":"2025-12-25T13:44:26.873878Z","shell.execute_reply.started":"2025-12-25T13:44:18.694601Z","shell.execute_reply":"2025-12-25T13:44:26.872717Z"}},"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-25T13:44:26.874997Z","iopub.execute_input":"2025-12-25T13:44:26.875290Z","iopub.status.idle":"2025-12-25T13:44:34.181641Z","shell.execute_reply.started":"2025-12-25T13:44:26.875269Z","shell.execute_reply":"2025-12-25T13:44:34.180356Z"}},"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-25T13:44:34.182935Z","iopub.execute_input":"2025-12-25T13:44:34.183245Z","iopub.status.idle":"2025-12-25T13:44:42.569639Z","shell.execute_reply.started":"2025-12-25T13:44:34.183224Z","shell.execute_reply":"2025-12-25T13:44:42.568461Z"}},"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} に保存しました。\")\n\n# save_custom_weights(model_baseline, file_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:44:42.572201Z","iopub.execute_input":"2025-12-25T13:44:42.572460Z","iopub.status.idle":"2025-12-25T13:44:42.578810Z","shell.execute_reply.started":"2025-12-25T13:44:42.572445Z","shell.execute_reply":"2025-12-25T13:44:42.577238Z"}},"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-25T13:44:42.579709Z","iopub.execute_input":"2025-12-25T13:44:42.579903Z","iopub.status.idle":"2025-12-25T13:44:42.602214Z","shell.execute_reply.started":"2025-12-25T13:44:42.579888Z","shell.execute_reply":"2025-12-25T13:44:42.601507Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## compile","metadata":{}},{"cell_type":"code","source":"model_Conv2dRBF.compile(optimizer=Adam(learning_rate=rl), loss='categorical_crossentropy', metrics=['categorical_accuracy', f1_score_metric])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:44:42.603556Z","iopub.execute_input":"2025-12-25T13:44:42.604391Z","iopub.status.idle":"2025-12-25T13:44:42.636719Z","shell.execute_reply.started":"2025-12-25T13:44:42.604369Z","shell.execute_reply":"2025-12-25T13:44:42.634831Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Train","metadata":{}},{"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-25T13:44:42.638093Z","iopub.execute_input":"2025-12-25T13:44:42.638387Z","iopub.status.idle":"2025-12-25T13:44:42.647969Z","shell.execute_reply.started":"2025-12-25T13:44:42.638364Z","shell.execute_reply":"2025-12-25T13:44:42.647110Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%time\nhst = model_Conv2dRBF.fit(x_train, y_cat_train, batch_size=512,\n                         #validation_data=(x_val, y_cat_val),\n                         #epochs=2,\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_Conv2dRBF, file_name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:44:58.641554Z","iopub.execute_input":"2025-12-25T13:44:58.642743Z","iopub.status.idle":"2025-12-25T13:44:58.674197Z","shell.execute_reply.started":"2025-12-25T13:44:58.642683Z","shell.execute_reply":"2025-12-25T13:44:58.673262Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"filename_base = file_name.replace('.weights.h5', '')\nfilename_base","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:44:59.836164Z","iopub.execute_input":"2025-12-25T13:44:59.836500Z","iopub.status.idle":"2025-12-25T13:44:59.842939Z","shell.execute_reply.started":"2025-12-25T13:44:59.836483Z","shell.execute_reply":"2025-12-25T13:44:59.841996Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_Conv2dRBF.save(f'{filename_base}.keras')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:45:01.212364Z","iopub.execute_input":"2025-12-25T13:45:01.212630Z","iopub.status.idle":"2025-12-25T13:45:01.302139Z","shell.execute_reply.started":"2025-12-25T13:45:01.212616Z","shell.execute_reply":"2025-12-25T13:45:01.301032Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_Conv2dRBF.save(f'{filename_base}.h5')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:45:02.969981Z","iopub.execute_input":"2025-12-25T13:45:02.970300Z","iopub.status.idle":"2025-12-25T13:45:03.027423Z","shell.execute_reply.started":"2025-12-25T13:45:02.970284Z","shell.execute_reply":"2025-12-25T13:45:03.026094Z"}},"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":"pred = model_test.predict(x_train[:100])\npred.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-12-25T13:45:24.784378Z","iopub.execute_input":"2025-12-25T13:45:24.784665Z","iopub.status.idle":"2025-12-25T13:45:24.897489Z","shell.execute_reply.started":"2025-12-25T13:45:24.784649Z","shell.execute_reply":"2025-12-25T13:45:24.896452Z"}},"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-25T13:45:28.601190Z","iopub.execute_input":"2025-12-25T13:45:28.602770Z","iopub.status.idle":"2025-12-25T13:45:36.889811Z","shell.execute_reply.started":"2025-12-25T13:45:28.602702Z","shell.execute_reply":"2025-12-25T13:45:36.888769Z"}},"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-25T13:45:36.891720Z","iopub.execute_input":"2025-12-25T13:45:36.892825Z","iopub.status.idle":"2025-12-25T13:45:44.237941Z","shell.execute_reply.started":"2025-12-25T13:45:36.892798Z","shell.execute_reply":"2025-12-25T13:45:44.236938Z"}},"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-25T13:45:44.238714Z","iopub.execute_input":"2025-12-25T13:45:44.238881Z","iopub.status.idle":"2025-12-25T13:45:52.798059Z","shell.execute_reply.started":"2025-12-25T13:45:44.238867Z","shell.execute_reply":"2025-12-25T13:45:52.796968Z"}},"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-25T13:45:52.799734Z","iopub.execute_input":"2025-12-25T13:45:52.799978Z","iopub.status.idle":"2025-12-25T13:46:01.098875Z","shell.execute_reply.started":"2025-12-25T13:45:52.799959Z","shell.execute_reply":"2025-12-25T13:46:01.097868Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 予測結果をKaggle CIFAR-10の提出ファイル形式に変換し、表示します。","metadata":{}},{"cell_type":"code","source":"predictions = model_Conv2dRBF.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}]}