{"cells":[{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"cell_type":"markdown","source":"## **Geoff's ok Kernel**\n\nJust a big mess at the moment\n\nThis page does some bad image manipulation and turns the images into a batch list for ml processing.\n\nIt crops the black and wide edges, resizes to 512 and poorly gamma corrects.\n\nModels still need to be saved and turned and used to process the test images."},{"metadata":{"trusted":true},"cell_type":"code","source":"#import a bunch of rubbish\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport tensorflow\nimport csv as csv\nfrom IPython.display import display\nimport cv2 \nfrom matplotlib import pyplot as plt\nimport operator\nfrom keras.models import Model\nfrom keras.layers import *\nfrom keras.activations import relu\nfrom keras.preprocessing.image import ImageDataGenerator\nfrom keras import backend\nimport os\nfrom random import shuffle \n    \n#LOSS AND METRICS FOR LEARNING ALGORITHM\ndef gacc(y_true, y_pred): #general accuracy\n    return 1-(backend.mean(backend.abs(y_pred - y_true), axis=-1))\n\ndef right_acc(y_true, y_pred): #general accuracy\n    return 1-(backend.mean(backend.minimum(backend.abs((backend.round(y_pred*4) - y_true*4)*4),1), axis=-1))\n\ndef mean_squared_error2(y_true, y_pred): #custom loss algorithm, actually a modded MAE\n    return backend.mean(backend.maximum((backend.abs(y_pred - y_true))-.02,0), axis=-1)\n\ndef std_error(y_true, y_pred): #std of the error\n    return backend.std((backend.abs(y_pred - y_true)))\n\ndef p_meanX(y_true, y_pred): #mean of all predictions - should ideally be .5\n    return backend.mean(y_pred, axis=-1)\n\ndef p_stdX(y_true, y_pred): #std of all predictions - should be ~0.32 to 0.35\n    return backend.std(y_pred)\n\n# Aaaaaaaaaaaaaaaaa","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"## Callable functions -- just shrink and hide this junk\n\ndef adjust_gamma(image, gamma=1.0): #old version of gamma correction\n    i = 0\n    invGamma = 1.0 / gamma\n    table = np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(0, 256)]).astype(\"uint8\")\n    return cv2.LUT(image, table)\n\ndef adjust_gamma2(img, gamma=1.0): #new colour balancer, normalises colour balance\n    new = [20,80,120]\n    newimge = np.zeros(512*512*3)\n    newimge = np.reshape(newimge,(512,512,3))\n    newimge[:,:,0] = img[:,:,0]*(min(2,(new[0] / np.mean(img[128:384,:,0]))))\n    newimge[:,:,1] = img[:,:,1]*(min(2,(new[1] / np.mean(img[128:384,:,1]))))\n    newimge[:,:,2] = img[:,:,2]*(min(2,(new[2] / np.mean(img[128:384,:,2]))))\n    newimge = np.clip(newimge,0,254)\n    img = newimge.astype(np.uint8)\n    return img\n\ndef autocrop(image, threshold=10): #is meant to get rid of the back borders (works most times)\n    if len(image.shape) == 3:\n        flatImage = np.max(image, 2)\n    else:\n        flatImage = image\n    assert len(flatImage.shape) == 2\n\n    rows = np.where(np.max(flatImage, 0) > threshold)[0]\n    if rows.size:\n        cols = np.where(np.max(flatImage, 1) > threshold)[0]\n        image = image[cols[0]: cols[-1] + 1, rows[0]: rows[-1] + 1]\n    else:\n        image = image[:1, :1]\n    return image\n\ndef im_resize(img): #crops to square, also calls autocrop,\n    img = autocrop(img)\n    height,width, x = img.shape\n    margin = 0\n    if(width>=height):\n        margin = int(np.floor((width-height)/2))\n        #print(height, width, margin)\n        crop_img = img[0:height,(width-height-margin):(height+margin)]\n    else:\n        margin = int(np.floor((width-height)/2))\n        #print(height, width, margin)\n        crop_img = img[(height-width-margin):(width+margin),0:width]\n    img = cv2.resize(img,(512,512),interpolation=cv2.INTER_AREA)\n    return img\n\n#im_avg returns a tuple of the inner area of the cropped 512x512 image\ndef im_avg(img):\n    return cv2.mean(img[100:412,100:412])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"# Image Manimpulation and Data Preparation\nfor dirname, _, filenames in os.walk(\"/kaggle/input/aptos2019-blindness-detection/train_images\"):\n    pass\n\ntrain = pd.read_csv('../input/aptos2019-blindness-detection/train.csv', header=0)\ntrain.diagnosis = train.diagnosis/4\n\ntrain_images = []\ntrain_labels = []\ncount = 0\ninitialCount = 0\ntagCount = [0,0,0,0,0]\n#nimg = {}\ntrain_images = np.zeros(512*512*1000*3).reshape(1000,512,512,3)   \nprint(np.shape(train_images))\n\nshuffle(filenames)\nfor filename in filenames:\n    if filename[(len(filename)-4):] == \".png\":\n        diag = train[train.id_code==filename[:-4]].diagnosis.item()\n        if (tagCount[int(diag*4)]<202) and (count<1000):    \n            tagCount[int(diag*4)] = tagCount[int(diag*4)]+1\n            img = cv2.imread(os.path.join(dirname, filename))\n            new_img = im_resize(img)\n            thisav = im_avg(new_img)\n            dgamma = thisav[0]+thisav[1]+thisav[2]\n            new_img = adjust_gamma2(new_img,(((400) / (50+dgamma))))\n            #nimg[filename[:-4]] = new_img\n            new_img = np.reshape(new_img,(512,512,3))\n            #new_img = np.divide(new_img,255.0)\n            train_images[count]=np.copy(new_img)\n            train_labels.append(train[train.id_code==filename[:-4]].diagnosis.item())\n            count = count+1\n            if count % 50 == 0: \n                print(count,tagCount)\n         #   if count % 1000 == 0: \n             #   break\ntrain_labels = np.asarray(train_labels)\nprint(tagCount)\nprint('done')"},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## ML Time!\n### the Model\n\nLabels and training images are loaded and done\n\n"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"###### The model(>?)\ndef resnext(a):\n    layers = 64 ##should be 256?\n    width = 32\n    arr = [a]\n    for i in range(width):\n       arr.append(Conv2D(4, (1, 1), activation='relu', padding='same')(a))\n       arr[i+1] = Conv2D(4, (3, 3), activation='relu', padding='same')(arr[i+1])\n       arr[i+1] = Conv2D(layers, (1, 1), activation='relu', padding='same')(arr[i+1])\n    return Add()(arr)\n    \na = Input(shape=(512,512,3))\n#x = BatchNormalization()(a)\nx = Conv2D(64, (3, 3), strides=2, activation='relu')(a)\nx = Conv2D(64, (3, 3), strides=2, activation='relu')(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = resnext(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = resnext(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = resnext(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = resnext(x)\nx = resnext(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = resnext(x)\nx = resnext(x)\nx = resnext(x)\nx = resnext(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = Conv2D(32, (1, 1), activation='relu')(x)\nx = Flatten()(x)\nb = Dense(1,activation='linear')(x)\n\nmodel = Model(inputs=a, outputs=b)\n#model.summary()"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"###### The model(>?)\ndef resnext(a):\n    layers = 64 ##should be 256?\n    width = 32\n    arr = [a]\n    for i in range(width):\n       arr.append(Conv2D(4, (1, 1), activation='elu', padding='same')(a))\n       arr[i+1] = Conv2D(4, (3, 3), activation='elu', padding='same')(arr[i+1])\n       arr[i+1] = Conv2D(layers, (1, 1), activation='elu', padding='same')(arr[i+1])\n    return Add()(arr)\n    \na = Input(shape=(512,512,3))\nx = BatchNormalization()(a)\nx = Conv2D(64, (3, 3), strides=2, activation='relu')(a)\nx = Conv2D(64, (3, 3), strides=2, activation='relu')(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = resnext(x)\nx = resnext(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = resnext(x)\nx = resnext(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = resnext(x)\nx = resnext(x)\nx = resnext(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = resnext(x)\nx = resnext(x)\nx = resnext(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = Flatten()(x)\nb = Dense(1,activation='linear')(x)\n\nmodel = Model(inputs=a, outputs=b)\n#model.summary()"},{"metadata":{"trusted":true},"cell_type":"code","source":"a = Input(shape=(512,512,3))\nx = Conv2D(128, (3, 3), strides=2, activation='relu')(a)\nx = Conv2D(128, (3, 3), strides=2, activation='relu')(x)\nx = Conv2D(128, (3, 3), strides=2, activation='relu')(x)\nx1 = Conv2D(128, (1, 1), activation='relu', padding='same')(x)\nx2 = Conv2D(128, (3, 3), activation='relu', padding='same')(x)\nx3 = Conv2D(128, (5, 5), activation='relu', padding='same')(x)\nx3a = MaxPooling2D(pool_size=(3, 3), strides=1, padding='same')(x)\nx = concatenate([x,x1,x2,x3,x3a], axis=-1)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = Conv2D(128, (1, 1), activation='relu')(x)\nx4 = Conv2D(64, (1, 1), activation='relu', padding='same')(x)\nx5 = Conv2D(64, (3, 3), activation='relu', padding='same')(x)\nx6 = Conv2D(64, (5, 5), activation='relu', padding='same')(x)\nx6a = MaxPooling2D(pool_size=(3, 3), strides=1,padding='same')(x)\nx = concatenate([x,x4,x5,x6,x6a], axis=-1)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = Conv2D(64, (1, 1), activation='elu')(x)\nx7 = Conv2D(64, (1, 1), activation='elu', padding='same')(x)\nx8 = Conv2D(64, (3, 3), activation='elu', padding='same')(x)\nx9 = Conv2D(64, (5, 5), activation='elu', padding='same')(x)\nx9a = MaxPooling2D(pool_size=(3, 3), strides=1,padding='same')(x)\nx = concatenate([x,x7,x8,x9,x9a], axis=-1)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = Conv2D(64, (1, 1), activation='elu')(x)\nx10 = Conv2D(64, (1, 1), activation='elu', padding='same')(x)\nx11 = Conv2D(64, (3, 3), activation='elu', padding='same')(x)\nx12 = Conv2D(64, (5, 5), activation='elu', padding='same')(x)\nx12a = MaxPooling2D(pool_size=(3, 3), strides=1,padding='same')(x)\nx = concatenate([x,x11,x12,x10,x12a], axis=-1)\nx = Conv2D(32, (1, 1), activation='elu')(x)\nx = MaxPooling2D(pool_size=(2, 2), strides=2, padding='valid')(x)\nx = AveragePooling2D(pool_size=(3, 3), strides=2, padding='valid')(x)\nx = Flatten()(x)\nb = Dense(1,activation='linear')(x)\nmodel = Model(inputs=a, outputs=b)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Running a model\nbatch_size = 32\nepochs = 300\n\ndatagen = ImageDataGenerator(\n    horizontal_flip=True,\n    vertical_flip=True\n #   brightness_range=(0.7,1.3),\n #   channel_shift_range=.3\n)\n\nmodel.compile(loss=mean_squared_error2, optimizer='adam', metrics=[right_acc, std_error,p_meanX,p_stdX ])\n#datagen.fit(train_images)\n\n#model.fit(x=train_images, y=train_labels, epochs=50, verbose =0,validation_split=0.1, shuffle=True) ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"### Model Generation Time!"},{"metadata":{"trusted":true},"cell_type":"code","source":"### Need to make a dataframe to do dataframe access of images and classications\n\n# probably should have done this in the image gen script\n\nfor dirname, _, filenames in os.walk('../input/12kimages/data/data/0/'): pass\ndirname=\"../input/12kimages/data/data/0/\"\ndatalabels0 = pd.DataFrame()\ndatalabels0['name'] = filenames\ndatalabels0['name'] = '0/' + datalabels0['name'].astype(str)\ndatalabels0['diagnosis'] = 0\n\nfor dirname, _, filenames in os.walk('../input/12kimages/data/data/1/'): pass\ndirname=\"../input/12kimages/data/data/1/\"\ndatalabels1 = pd.DataFrame()\ndatalabels1['name'] = filenames\ndatalabels1['name'] = '1/' + datalabels1['name'].astype(str)\ndatalabels1['diagnosis'] = .25\n\nfor dirname, _, filenames in os.walk('../input/12kimages/data/data/2/'): pass\ndirname=\"../input/12kimages/data/data/2/\"\ndatalabels2 = pd.DataFrame()\ndatalabels2['name'] = filenames\ndatalabels2['name'] = '2/' + datalabels2['name'].astype(str)\ndatalabels2['diagnosis'] = .5\n\nfor dirname, _, filenames in os.walk('../input/12kimages/data/data/3/'): pass\ndirname=\"../input/12kimages/data/data/3/\"\ndatalabels3 = pd.DataFrame()\ndatalabels3['name'] = filenames\ndatalabels3['name'] = '3/' + datalabels3['name'].astype(str)\ndatalabels3['diagnosis'] = .75\n\nfor dirname, _, filenames in os.walk('../input/12kimages/data/data/4/'): pass\ndirname=\"../input/12kimages/data/data/4/\"\ndatalabels4 = pd.DataFrame()\ndatalabels4['name'] = filenames\ndatalabels4['name'] = '4/' + datalabels4['name'].astype(str)\ndatalabels4['diagnosis'] = 1\n\ndatalabels = pd.DataFrame().append([datalabels0, datalabels1, datalabels2, datalabels3, datalabels4],ignore_index = True)\ndatalabels['name'] = datalabels['name'].astype(str)\n#datalabels","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"type(datalabels['name'][3])","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"the_flow = datagen.flow_from_dataframe(datalabels, directory='../input/12kimages/data/data',x_col='name',y_col='diagnosis',class_mode='raw',target_size=(512, 512), batch_size=32)\nhist = model.fit_generator(the_flow,\n                   use_multiprocessing=False, shuffle=True, workers=1,steps_per_epoch=100,epochs=epochs,verbose =2)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"#### Old from directory code\nhist = model.fit_generator(datagen.flow_from_directory('../input/imagegen-test/data/data',target_size=(512, 512), batch_size=32),\n                   use_multiprocessing=False, shuffle=True, workers=1,steps_per_epoch=150,epochs=epochs,verbose =1)"},{"metadata":{"trusted":true},"cell_type":"markdown","source":"#### Old from memory code\nhist = model.fit_generator(datagen.flow(train_images, train_labels, batch_size=32),\n                   use_multiprocessing=False, shuffle=True, workers=1,steps_per_epoch=150,epochs=epochs, verbose =2)\n"},{"metadata":{},"cell_type":"markdown","source":"### Quick prediction check\n[real diagnosis, prediction, actual prediction]"},{"metadata":{"trusted":true},"cell_type":"code","source":"real_pred = abs(model.predict(train_images))*4\npred = np.round(real_pred)\nreal = np.round(abs(np.asarray(train_labels))*4)\n\nfor i in range(100):\n    print(real[i], pred[i],real_pred[i])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Sanity Check\nChecks the model against all the training data - as we only used a subsample of 1000 images, that leaves 2662 images as well as the originals\ngood is good, bad is bad and the array is which images were not detected properly"},{"metadata":{"trusted":true},"cell_type":"code","source":"for dirname, _, filenames in os.walk('/kaggle/input/aptos2019-blindness-detection/train_images'):\n    pass\ndirname=\"/kaggle/input/aptos2019-blindness-detection/train_images\"\n    \ntrain = pd.read_csv('../input/aptos2019-blindness-detection/train.csv', header=0)\ntrain['diagnosis_2'] = 0\ntrain['diagnosis_3'] = 0\nbad = [0,0,0,0,0]\n#del train_images\n#del train_labels\ncount = 0\naccurat = 0\ninaccurat = 0\n#nimg = {}\nfor filename in filenames:\n    if filename[(len(filename)-4):] == \".png\":\n        img = cv2.imread(os.path.join(dirname, filename))\n        new_img = im_resize(img)\n        thisav = im_avg(new_img)\n        dgamma = thisav[0]+thisav[1]+thisav[2]\n        new_img = adjust_gamma2(new_img,(((400) / dgamma)))\n        #new_img = np.divide(new_img,255.0)\n        count = count+1\n        k = np.reshape(new_img,(1,512,512,3))\n        \n        real_pred = min(4,max(0,model.predict(k)[0][0]*4))\n        pred = int(real_pred)  #np.round(real_pred)\n        real = train[train.id_code==filename[:-4]].diagnosis.item()\n        train.loc[train.id_code==filename[:-4],'diagnosis_2']=int(pred)\n        #train.loc[train.id_code==filename[:-4],'diagnosis_3']=real_pred\n        #print(real, \" \", pred, \" \",real_pred)\n        if int(pred) == real:\n            accurat +=1\n        else:\n            inaccurat +=1\n            bad[real] += 1\n        if count % 100 == 0: \n            print(count, \" - Good: \",accurat, \" n Bad: \",inaccurat, \" - Bad: \",bad)\n \ntrain","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Final Output Processing\nThis runs over the test sets and makes a final result submission.csv"},{"metadata":{"trusted":true},"cell_type":"code","source":"for dirname, _, filenames in os.walk('/kaggle/input/aptos2019-blindness-detection/test_images'):\n    pass\ndirname=\"/kaggle/input/aptos2019-blindness-detection/test_images\"\n    \ntest = pd.read_csv('../input/aptos2019-blindness-detection/test.csv', header=0)\ntest['diagnosis'] = 0\n\ntest_images = []\ntest_labels = []\ncount = 0\n#nimg = {}\nfor filename in filenames:\n    if filename[(len(filename)-4):] == \".png\":\n        img = cv2.imread(os.path.join(dirname, filename))\n        new_img = im_resize(img)\n        thisav = im_avg(new_img)\n        dgamma = thisav[0]+thisav[1]+thisav[2]\n        new_img = adjust_gamma2(new_img,(((400) / dgamma)))\n        #new_img = np.divide(new_img,255.0)\n        count = count+1\n        #nimg[filename[:-4]] = new_img\n        k = np.reshape(new_img,(1,512,512,3))\n       # print(np.shape(k), np.shape(test_images))\n        #if len(test_images) ==0:\n        #    test_images = np.copy(k)\n        #else:\n        #    test_images=np.vstack([test_images,k])\n        #test_labels.append(test[test.id_code==filename[:-4]].diagnosis.item())\n        real_pred = min(4,max(0,model.predict(k)[0][0]*4))\n        pred = int(real_pred)  #np.round(real_pred)\n        test.loc[test.id_code==filename[:-4],'diagnosis']=int(pred)\n       # print(pred, int(pred))\n        \n        if count % 50 == 0: \n            print(count)\n     #   if count % 1000 == 0: \n            #break\n#test_labels = np.asarray(test_labels)    \ntest.to_csv('submission.csv',index=False)\ntest\n#pred = np.round(abs(model.predict(test_images))*4)\n#print(pred)","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":1}