{"cells":[{"metadata":{},"cell_type":"markdown","source":"## This notebook is just for test.\n## This cannot make a complete model because of memory error.\n## Thank you."},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"code","source":"\nimport numpy as np \nimport pandas as pd \n\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 1.前回データの確認"},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"path = \"../input/eda-for-biginner-updated-to-english-ver\"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"traindf = pd.read_csv(path+\"/traindf.csv\")\ntraindf","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# おさらい"},{"metadata":{"trusted":true},"cell_type":"code","source":"tmp = traindf[traindf[\"landmark_id\"]==7]\ntmp","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import cv2\nimport matplotlib.pyplot as plt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for a in tmp[\"path\"]:\n    img = cv2.imread(a)\n    plt.figure()\n    plt.imshow(img)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# おさらい2　import collectionを使って、各idの個数を数えた。それをcount数ごとに並べたのが、dfcnt"},{"metadata":{"trusted":true},"cell_type":"code","source":"dfcnt = pd.read_csv(path+\"/dfcnt.csv\")\ndfcnt","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.scatter(dfcnt[\"id\"],dfcnt[\"count\"])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# この時点で、landmark idの種類は全部で81313個、最小枚数は2枚であることがわかる(前回は138982が6272個に注目してた)ので、\n# 各landmark idごとに1枚訓練データ(traindata)、１枚検証データ(validation)にしてpytorchでモデルを作成することを考える。"},{"metadata":{"trusted":true},"cell_type":"code","source":"traindf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"dfcnt","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## dfcntのidでfilteringして、一番上にきたやつをtrain data, 上から2つ目をvalidationとする\n## わかりやすくするため、１個で説明"},{"metadata":{"trusted":true},"cell_type":"code","source":"tmp1 = dfcnt[\"id\"].iloc[0]\ntmp1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tmpdf1 = traindf[traindf[\"landmark_id\"]==tmp1]\ntmpdf1","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tlist = []\nvlist = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tlist.append(tmpdf1.iloc[0].values)\ntlist","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"vlist.append(tmpdf1.iloc[1].values)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# これを繰り返す","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"from tqdm import tqdm","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"import os\nos.path.exists(\"./tdf.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tlist = []\nvlist = []","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if os.path.exists(\"./tdf.csv\")==False:\n    \n\n    \n\n    tmp1 = dfcnt[\"id\"].values #.valuesでnumpy. for文はnumpyのほうが早いときがある。\n\n    for a in tqdm(range(len(dfcnt))):\n\n        tmpdf1 = traindf[traindf.landmark_id.values==tmp1[a]]\n        tlist.append(tmpdf1.iloc[0].values)\n        vlist.append(tmpdf1.iloc[1].values)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tdf = pd.DataFrame(tlist,columns=tmpdf1.columns)\ntdf[\"repair_id\"]=np.arange(0,len(tdf),1)\ntdf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"vdf = pd.DataFrame(vlist,columns=tmpdf1.columns)\nvdf[\"repair_id\"]=np.arange(0,len(vdf),1)\nvdf","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"if os.path.exists(\"./tdf.csv\"):\n    tdf = pd.read_csv(\"./tdf.csv\")\n    vdf = pd.read_csv(\"./vdf.csv\")","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tdf.to_csv(\"tdf.csv\",index=False)\nvdf.to_csv(\"vdf.csv\",index=False)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 全部やっても良いが、自分で作成するときは10枚くらいでテストするほうが効率的"},{"metadata":{"trusted":true},"cell_type":"code","source":"tdf2 = tdf.iloc[:10,:]\nvdf2 = vdf.iloc[:10,:]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"tdf2","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"vdf2","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# ここからpytorch"},{"metadata":{"trusted":true},"cell_type":"code","source":"import torch\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch import nn, optim\nfrom torch.nn import functional as F\nfrom torchvision.models import resnet18\nfrom albumentations import Normalize, Compose\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport cv2\nfrom tqdm.notebook import tqdm\nfrom sklearn.model_selection import train_test_split\nimport os\nimport glob\nimport multiprocessing as mp\n\n\n\nif torch.cuda.is_available():\n    device = 'cuda:0'\n    torch.set_default_tensor_type('torch.cuda.FloatTensor')\nelse:\n    device = 'cpu'\nprint(f'Running on device: {device}')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# このサイトがとても分かりやすく書いてくれているので、迷ったらここを見る\nhttps://qiita.com/takurooo/items/e4c91c5d78059f92e76d"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 1. transformの定義"},{"metadata":{"trusted":true},"cell_type":"code","source":"preprocess = Compose([\n    Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], p=1)\n])\n\n# resnextなどのpre-trainモデルは全て、同じ方法で正規化された入力画像を使用しなければならない。それの変換をこの関数で行う。値はdefault。\n# Composeは今回あまり、意味をなさない\n# https://betashort-lab.com/%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9/albumentations%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81/ に詳細は書いてある","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 2. Dataset"},{"metadata":{"trusted":true},"cell_type":"code","source":"# 画像をどれだけ小さくするかの処理\nROWS = 32\nCOLS = 32","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class GLDataset(Dataset):\n    \n    def __init__(self,img_pass,labels,preprocess=None):\n        self.img_pass = img_pass\n        self.labels = labels\n        self.preprocess = preprocess\n        \n    def __len__(self):\n        return len(self.img_pass)\n    \n    def __getitem__(self,idx):\n        \n        # ここからdatasetに食わせる前の前処理の記述。\n        \n        img_pass = self.img_pass[idx]\n        label = self.labels[idx]\n        \n        land = cv2.imread(img_pass)\n        land = cv2.resize(land,(ROWS,COLS),interpolation = cv2.INTER_CUBIC)\n        land = cv2.cvtColor(land,cv2.COLOR_BGR2RGB) # augmentを使うときにBGRからRGBにする必要があるのかもしれない。\n        \n        if self.preprocess is not None: # ここで、前処理を入れてnormalizationしている。\n                augmented = self.preprocess(image=land) # preprocessのimageをfaceで読む\n                land = augmented['image'] # https://betashort-lab.com/%E3%83%87%E3%83%BC%E3%82%BF%E3%82%B5%E3%82%A4%E3%82%A8%E3%83%B3%E3%82%B9/albumentations%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81/　に書いてある\n                \n        return {'landmarks': land.transpose(2, 0, 1), 'label': np.array(label, dtype=int)}  # pytorchはchannnl, x, yの形。これは辞書型で返している。(扱いやすいというだけかも。)\n        \n        \n        \n        \n        \n        \n        \n        ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 1つ1つ追って、何やっているかを見ていく。"},{"metadata":{"trusted":true},"cell_type":"code","source":"land = cv2.imread(tdf2[\"path\"].iloc[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.imshow(land)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"land = cv2.resize(land,(ROWS,COLS),interpolation = cv2.INTER_CUBIC)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.imshow(land)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"land = cv2.cvtColor(land,cv2.COLOR_BGR2RGB) # augmentを使うときにBGRからRGBにする必要があるのかもしれない。","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.imshow(land)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"augmented = preprocess(image=land) # preprocessのimageをfaceで読む\nland = augmented['image']","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.imshow(land)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"land.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"land=land.transpose(2, 0, 1)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"land.shape","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Datasetのinstance化"},{"metadata":{"trusted":true},"cell_type":"code","source":"# instance化\ntrain_dataset = GLDataset(\n    img_pass=tdf2[\"path\"],\n    labels=tdf2[\"repair_id\"].to_numpy(),\n    preprocess=preprocess\n)\n#val_dataset = FaceValDataset(\n\nval_dataset = GLDataset(\n    img_pass=vdf2[\"path\"],\n    labels=vdf2[\"repair_id\"].to_numpy(),\n    preprocess=preprocess\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"print(train_dataset[0])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 3. DataLoader"},{"metadata":{"trusted":true},"cell_type":"code","source":"BATCH_SIZE = 2\n\n#NUM_WORKERS = mp.cpu_count()\n#NUM_WORKERS = 0 # ここを0にしないと動かない。cpuの仕様個数。←実は動くことが判明。classの中身次第！","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"NUM_WORKERS = mp.cpu_count()\nNUM_WORKERS","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"## DataLoaderはimport torch.utils.data.Datasetでimport済みのもの\ntrain_dataloader = DataLoader(\n    train_dataset,\n    batch_size=BATCH_SIZE,\n    shuffle=False, #https://schemer1341.hatenablog.com/entry/2019/01/06/024605 を参考. idがわからなくなる\n    num_workers=NUM_WORKERS\n)\nval_dataloader = DataLoader(\n    val_dataset,\n    batch_size=BATCH_SIZE,\n    shuffle=False,\n    num_workers=NUM_WORKERS\n)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 初日はここまでかな・・・"},{"metadata":{"trusted":true},"cell_type":"code","source":"encoder = resnet18(pretrained = True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"class LandmarkClassifier(nn.Module):\n    \n    def __init__(self,encoder,in_channels=3,num_classes = len(dfcnt)):\n        \n        super(LandmarkClassifier,self).__init__()\n        # super().init__()\n        \n        self.encoder = encoder\n        \n        self.encoder.conv1 = nn.Conv2d(\n        \n        in_channels,\n            64,\n            kernel_size=7,\n            stride=2,\n            padding = 3,\n            bias = False      \n        \n        \n        )\n        \n        self.encoder.fc = nn.Linear(512*1,num_classes)\n        \n    def forward(self,x):\n        \n        return self.encoder(x)       \n        \n        \n    \n    \n    \n    \n    \n    \n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"classifier = LandmarkClassifier(encoder = encoder,in_channels = 3, num_classes = len(dfcnt))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# classifier = classifier.to(device)\n\nclassifier.train()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"optimizer = optim.Adam(classifier.parameters(),lr=1e-6)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# モデルを作成していく"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## 効率的なやり方\n## Process 1 : Simpleにしてできるところからやる。例えば1つだけやる\n## Process 2 : いったんまとめてみる\n## Process 3 : for文にして回してみる\n## Process 4 : 汎用性を持たせる (数字 → 文字化)\n## Process 5 : さらに汎用性を持たせる (関数化)\n## Process 6 : class化する"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 1 epochの流れを見ていく まずはtrainから"},{"metadata":{"trusted":true},"cell_type":"code","source":"classifier.train()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"train_dataloader[0]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for a in train_dataloader:\n    print(a)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for a in train_dataloader:\n    y_pred = classifier(a[\"landmarks\"])\n    print(y_pred)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# 正解と予測の lossを求める"},{"metadata":{"trusted":true},"cell_type":"code","source":"for a in train_dataloader:\n    y_pred = classifier(a[\"landmarks\"])\n    \n    label = a[\"label\"]\n    \n    loss = criterion(y_pred,label)\n    print(loss)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for a in train_dataloader:\n    y_pred = classifier(a[\"landmarks\"])\n    \n    label = a[\"label\"]\n    \n    loss = criterion(y_pred,label)\n    print(loss.item())","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"for a in train_dataloader:\n    y_pred = classifier(a[\"landmarks\"])\n    \n    label = a[\"label\"]\n    \n    loss = criterion(y_pred,label)\n    print(loss.item())\n    \n    optimizer.zero_grad()\n    loss.backward()\n    optimizer.step()\n    \n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# epochを回すことを考えると、lossを保存"},{"metadata":{"trusted":true},"cell_type":"code","source":"trainloss = []\n\nfor a in train_dataloader:\n    y_pred = classifier(a[\"landmarks\"])\n    \n    label = a[\"label\"]\n    \n    loss = criterion(y_pred,label)\n    \n    optimizer.zero_grad()\n    loss.backward()\n    optimizer.step()\n    \ntrainloss.append(loss.item())\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"trainloss","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def trainmodel(train_dataloader):\n    \n    classifier.train()\n \n    for a in train_dataloader:\n        y_pred = classifier(a[\"landmarks\"])\n\n        label = a[\"label\"]\n\n        loss = criterion(y_pred,label)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n    return(loss.item())\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# validationを同様に作る"},{"metadata":{"trusted":true},"cell_type":"code","source":"def valmodel(val_dataloader):\n    \n    classifier.eval()\n \n    for a in val_dataloader:\n        y_pred = classifier(a[\"landmarks\"])\n\n        label = a[\"label\"]\n\n        loss = criterion(y_pred,label)\n    \n    return(loss.item())\n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# くっつけてepochで回す"},{"metadata":{"trusted":true},"cell_type":"code","source":"epochs = 10","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"trainloss = []\nvalloss= []\n\nfor a in tqdm(range(epochs)):\n   \n    trainloss.append(trainmodel(train_dataloader))\n    valloss.append(valmodel(val_dataloader))","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = np.arange(epochs)\nplt.scatter(x,trainloss)\nplt.scatter(x,valloss)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# modelをsaveする"},{"metadata":{"trusted":true},"cell_type":"code","source":"trainloss = []\nvalloss= []\n\nbestloss = None\nsavename = \"resnet18.pth\"\n\nfor a in tqdm(range(epochs)):\n   \n    trainloss.append(trainmodel(train_dataloader))\n    valloss.append(valmodel(val_dataloader))\n    \n    if bestloss is None:\n        bestloss = valloss[-1]\n        state = {\n            \"state_dict\":classifier.state_dict(),\n            \"optimizer_dict\":optimizer.state_dict(),\n            \"bestloss\" : bestloss\n        }\n        \n        torch.save(state,savename)\n        \n        print(\"save the first model\")\n        \n    elif valloss[-1] < bestloss:\n        bestloss = valloss[-1]\n        state = {\n            \"state_dict\":classifier.state_dict(),\n            \"optimizer_dict\":optimizer.state_dict(),\n            \"bestloss\" : bestloss\n        }\n        \n        torch.save(state,savename)\n        \n        print(\"found the better point\")\n    \n    else:\n        pass\n        \n    \n    \n    ","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = np.arange(epochs)\nplt.scatter(x,trainloss)\nplt.scatter(x,valloss)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def savemodel(bestloss,valloss):\n    if bestloss is None:\n        bestloss = valloss[-1]\n        state = {\n            \"state_dict\":classifier.state_dict(),\n            \"optimizer_dict\":optimizer.state_dict(),\n            \"bestloss\" : bestloss\n        }\n        \n        torch.save(state,savename)\n        \n        print(\"save the first model\")\n        \n    elif valloss[-1] < bestloss:\n        bestloss = valloss[-1]\n        state = {\n            \"state_dict\":classifier.state_dict(),\n            \"optimizer_dict\":optimizer.state_dict(),\n            \"bestloss\" : bestloss\n        }\n        \n        torch.save(state,savename)\n        \n        print(\"found the better point\")\n    \n    else:\n        pass\n    \n    return bestloss","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"trainloss = []\nvalloss= []\n\nbestloss = None\nsavename = \"resnet18.pth\"\n\nfor a in tqdm(range(epochs)):\n   \n    trainloss.append(trainmodel(train_dataloader))\n    valloss.append(valmodel(val_dataloader))\n    \n    bestloss = savemodel(bestloss,valloss)\n        \n    \n    \n    \n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"x = np.arange(epochs)\nplt.scatter(x,trainloss)\nplt.scatter(x,valloss)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat":4,"nbformat_minor":4}