├── CODE.zip ├── data_generation.py ├── data_ops.py ├── initialization.py ├── mask_modulation_model.py ├── onn_mask_testing.py ├── onn_mask_train.py ├── tf_OpticsModule.py └── virtual_networks.py /CODE.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/UCLACOMPSCI/Image-Classification/0df1c9b1b232ee4a6d603a748653bc8126fff42b/CODE.zip -------------------------------------------------------------------------------- /data_generation.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Data Generation 3 | ''' 4 | import numpy as np 5 | import data_ops as dto 6 | import tensorflow as tf 7 | import initialization as init 8 | 9 | tc = init.init_params() 10 | 11 | if tc.TRAINING_DATA_TYPE == 'mnist' or tc.TESTING_DATA_TYPE == 'mnist': 12 | data = tf.keras.datasets.mnist.load_data() 13 | 14 | if tc.TRAINING_DATA_TYPE == 'cifar10' or tc.TESTING_DATA_TYPE == 'cifar10': 15 | data = tf.keras.datasets.cifar10.load_data() 16 | 17 | if tc.TRAINING_DATA_TYPE == 'fashion-mnist' or tc.TESTING_DATA_TYPE == 'fashion-mnist': 18 | data = tf.keras.datasets.fashion_mnist.load_data() 19 | 20 | # separating dataset components 21 | train, test = data 22 | data_train, label_train = train 23 | data_test, label_test = test 24 | global_norm = np.amax([np.amax(np.abs(data_train)), np.amax(np.abs(data_test))]) 25 | # print(global_norm) 26 | 27 | # Create Validation Set 28 | indices_valid = dto.create_validation(label_train, label_test, tc.validation_ratio) 29 | data_valid = data_train[indices_valid] 30 | label_valid = label_train[indices_valid] 31 | N_VALID = np.amax(label_valid.shape) 32 | data_train = np.delete(data_train, indices_valid, axis=0) 33 | label_train = np.delete(label_train, indices_valid) 34 | 35 | gts = tf.zeros((tc.NUM_CLASS, tc.M, tc.N),dtype=tf.float32) 36 | padxgt = int((tc.M - tc.SENSOR_ROW) / 2) 37 | padygt = int((tc.N - tc.SENSOR_COL) / 2) 38 | for i in range(tc.NUM_CLASS): 39 | gt_i = dto.gt_generator_classification(i) 40 | gt_p = tf.pad(gt_i, ((padxgt, padxgt), (padygt, padygt)), 'constant') 41 | gt_p = tf.expand_dims(gt_p, 0) 42 | gts = tf.add(gts,tf.scatter_nd([[i]], gt_p, shape=[tc.NUM_CLASS, tc.M, tc.N])) 43 | 44 | gts_tensor = gts #tf.convert_to_tensor(gts,dtype=tf.float32) 45 | 46 | def _preprocess(img, label): 47 | 48 | img_r = tf.reshape(img, [tc.DATA_ROW, tc.DATA_COL, 1]) 49 | img_r = tf.image.resize_images(img_r, [tc.OBJECT_ROW, tc.OBJECT_COL],align_corners=True) 50 | img_r = tf.reshape(img_r, [tc.OBJECT_ROW, tc.OBJECT_COL]) 51 | img_r = tf.divide(img_r,global_norm) 52 | 53 | # print(img_r) 54 | 55 | padx = int((tc.M - tc.OBJECT_ROW) / 2) 56 | pady = int((tc.N - tc.OBJECT_COL) / 2) 57 | img_pad = tf.pad(img_r, [(padx, padx), (pady, pady)], 'constant') 58 | 59 | label = tf.cast(label,dtype=tf.int64) 60 | gt = tf.squeeze(tf.slice(gts_tensor, [label, 0, 0,], [1, tc.M, tc.N])) 61 | 62 | if tc.OBJECT_AMPLITUDE_INPUT is True: 63 | img_amp = img_pad*100 64 | img_phase = tf.zeros((tc.M,tc.N),dtype=tf.float32) 65 | elif tc.OBJECT_PHASE_INPUT is True: 66 | img_amp = 100*tf.ones((tc.OBJECT_ROW,tc.OBJECT_COL), dtype=tf.float32) 67 | img_amp = tf.pad(img_amp, [(padx, padx), (pady, pady)], 'constant') 68 | img_phase = 1.999 * np.pi * img_pad/(tf.reduce_max(img_pad)) 69 | 70 | return img_amp, img_phase, gt, label 71 | 72 | # The following functions return TF operation for getting the next 73 | # training, validation, or testing data batch 74 | def get_data_batch(request_type): 75 | 76 | if request_type == 'training': 77 | get_batch = tf.data.Dataset.from_tensor_slices((data_train, label_train)) 78 | get_batch = get_batch.shuffle(tc.NUMBER_TRAINING_ELEMENTS-N_VALID) 79 | 80 | elif request_type == 'testing': 81 | get_batch = tf.data.Dataset.from_tensor_slices((data_test, label_test)) 82 | get_batch = get_batch.shuffle(tc.NUMBER_TEST_ELEMENTS) 83 | 84 | elif request_type == 'validation': 85 | get_batch = tf.data.Dataset.from_tensor_slices((data_valid, label_valid)) 86 | get_batch = get_batch.shuffle(N_VALID) 87 | 88 | get_batch = get_batch.map(_preprocess, 4) 89 | get_batch = get_batch.prefetch(buffer_size=tc.BATCH_SIZE*100) 90 | get_batch = get_batch.batch(tc.BATCH_SIZE, drop_remainder = True) 91 | 92 | return get_batch#, init_val -------------------------------------------------------------------------------- /data_ops.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import cv2 3 | import initialization as init 4 | 5 | tc = init.init_params() 6 | 7 | def find_nearest(self,a): 8 | 9 | A = np.asarray(self) 10 | idx = (np.abs(A-a)).argmin() 11 | return A[idx],idx 12 | 13 | #SENSOR-PLANE DESIGN based on SENSOR REGION WIDTH, CLASS/LABEL-SIZE and NUMBER of DETECTORS 14 | def sensorplane_geometry(): 15 | 16 | fl_num_det_row = int(np.floor(tc.NUM_CLASS**(0.5))) 17 | ce_num_det_row = int(np.ceil(tc.NUM_CLASS**(0.5))) 18 | 19 | choices = np.asarray([fl_num_det_row,ce_num_det_row]) 20 | square_arrgmnt = choices**2 21 | remain_det = np.abs(tc.NUM_CLASS-square_arrgmnt) 22 | slct = np.argmin(remain_det) 23 | slct_ = np.mod(slct+1,2) 24 | rows_label = choices[slct] 25 | col_distribution = np.ones((rows_label,1))*rows_label 26 | col_distribution[rows_label//2-remain_det[slct]//2:rows_label//2-remain_det[slct]//2+remain_det[slct]] = choices[slct_] 27 | nDet = int(np.amin(col_distribution)) 28 | NDet = int(np.amax(col_distribution)) 29 | 30 | LABEL_ROW = int(np.round(tc.CLASS_SIZE_X/tc.DX)) #Vertical label size 31 | LABEL_COL = int(np.round(tc.CLASS_SIZE_Y/tc.DY)) #Horizontal label size 32 | 33 | marginX = (tc.SENSOR_WX-nDet*tc.CLASS_SIZE_X)/2/nDet 34 | marginY_1 = (tc.SENSOR_WY-nDet*tc.CLASS_SIZE_Y)/2/nDet 35 | marginY_2 = (tc.SENSOR_WY-NDet*tc.CLASS_SIZE_Y)/2/NDet 36 | 37 | cont_cell_locs = np.zeros((tc.NUM_CLASS,2)) 38 | cell_locs = np.zeros((tc.NUM_CLASS,2)) 39 | sensorx = (np.arange(tc.SENSOR_ROW)-(tc.SENSOR_ROW-1)/2)*tc.DX 40 | sensory = (np.arange(tc.SENSOR_COL)-(tc.SENSOR_COL-1)/2)*tc.DY 41 | ULC_sensorX = -(tc.SENSOR_ROW-1)/2*tc.DX 42 | ULC_sensorY = -(tc.SENSOR_COL-1)/2*tc.DY 43 | det_count = 0 44 | label_fields = np.zeros((tc.NUM_CLASS,tc.SENSOR_ROW,tc.SENSOR_COL)) 45 | for rr in range(rows_label): 46 | mdet = int(col_distribution[rr]) 47 | for md in range(mdet): 48 | if(mdet==nDet): 49 | cont_cell_locs[det_count,:] = np.asarray([ULC_sensorX+rr*tc.CLASS_SIZE_X+(2*rr+1)*marginX,ULC_sensorY+md*tc.CLASS_SIZE_Y+(2*md+1)*marginY_1]) 50 | vx,qx = find_nearest(sensorx,cont_cell_locs[det_count,0]) 51 | vy,qy = find_nearest(sensory,cont_cell_locs[det_count,1]) 52 | cell_locs[det_count,:] = [qx,qy] 53 | label_fields[det_count,qx:qx+LABEL_ROW,qy:qy+LABEL_COL] = 1 54 | else: 55 | cont_cell_locs[det_count,:] = np.asarray([ULC_sensorX+rr*tc.CLASS_SIZE_X+(2*rr+1)*marginX,ULC_sensorY+md*tc.CLASS_SIZE_Y+(2*md+1)*marginY_2]) 56 | vx,qx = find_nearest(sensorx,cont_cell_locs[det_count,0]) 57 | vy,qy = find_nearest(sensory,cont_cell_locs[det_count,1]) 58 | cell_locs[det_count,:] = [qx,qy] 59 | label_fields[det_count,qx:qx+LABEL_ROW,qy:qy+LABEL_COL] = 1 60 | det_count = det_count+1 61 | 62 | cell_locs = cell_locs.astype('int') 63 | thecell=np.ones((LABEL_ROW,LABEL_COL)) 64 | 65 | return cell_locs, thecell, label_fields, col_distribution 66 | 67 | if tc.APPLICATION == 'classification': 68 | global cell_locs 69 | global thecell 70 | cell_locs, thecell, label_fields, col_distribution = sensorplane_geometry() 71 | 72 | def object_rotation(self): 73 | u = self 74 | angle = np.random.randint(-90,90) 75 | R = cv2.getRotationMatrix2D((tc.N/2,tc.M/2),angle,1) 76 | u = cv2.warpAffine(u,R,(tc.N,tc.M)) 77 | return u 78 | 79 | def object_resampling_DATA2OBJ(self): 80 | 81 | u = self 82 | up_u = np.zeros((tc.OBJECT_ROW, tc.OBJECT_COL), dtype=np.uint8) 83 | up_u = cv2.resize(u, (np.int(tc.OBJECT_COL),np.int(tc.OBJECT_ROW))) 84 | return up_u 85 | 86 | def object_resampling_DATA2SENSOR(self): 87 | 88 | u = self 89 | up_u = np.zeros((tc.SENSOR_ROW, tc.SENSOR_COL), dtype=np.uint8) 90 | up_u = cv2.resize(u, (np.int(tc.SENSOR_COL),np.int(tc.SENSOR_ROW))) 91 | return up_u 92 | 93 | def gt_generator_classification(cls): 94 | 95 | gt_sensor = np.zeros((tc.SENSOR_ROW, tc.SENSOR_COL), dtype=np.float32) 96 | cellindex = cls 97 | ulcorner = cell_locs[cellindex,0:2] 98 | gt_sensor[ulcorner[0]:ulcorner[0]+thecell.shape[0], 99 | ulcorner[1]:ulcorner[1]+thecell.shape[1]] = thecell 100 | 101 | return gt_sensor 102 | 103 | 104 | def int_to_one_hot(cls): 105 | oh = np.zeros((tc.NUM_CLASS)) 106 | oh[cls] = 1 107 | return oh 108 | 109 | def create_validation(label_train, label_test, ratio): 110 | N_TEST = np.amax(label_test.shape) 111 | N_TRAIN = np.amax(label_train.shape) 112 | N_VAL = int(N_TEST*ratio) 113 | N_cls_val = int(np.round(N_VAL/tc.NUM_CLASS)) 114 | ind_val = np.zeros((N_VAL)) 115 | indexes = np.arange(N_TRAIN) 116 | for cls in range(tc.NUM_CLASS): 117 | ind_cls = indexes[label_train==cls] 118 | Ncls = int(np.sum([label_train==cls])) 119 | begin = cls*N_cls_val 120 | rand_ind = ind_cls[np.random.randint(0,Ncls,size=[2*N_cls_val,1])] 121 | R = np.random.permutation(np.unique(rand_ind)) 122 | ind_val[begin:begin+N_cls_val] = R[0:N_cls_val] 123 | 124 | return ind_val.astype('int32') -------------------------------------------------------------------------------- /initialization.py: -------------------------------------------------------------------------------- 1 | from configobj import ConfigObj 2 | import numpy as np 3 | def init_params(): 4 | 5 | ''' 6 | tc : training_configuration 7 | ''' 8 | # USER-DEFINED GLOBAL PARAMETERS 9 | tc = ConfigObj() 10 | tc.APPLICATION = 'classification' 11 | tc.WLENGTH, tc.ridx = 0.75e-3, 1.72499 12 | tc.M, tc.N = 512, 512 13 | tc.DX, tc.DY = 0.4e-3, 0.4e-3 14 | tc.MASK_WX, tc.MASK_WY = 8e-2, 8e-2 15 | tc.DATA_ROW, tc.DATA_COL = 28, 28 16 | tc.OBJ_WX, tc.OBJ_WY = 3.36e-2, 3.36e-2 17 | tc.SENSOR_WX, tc.SENSOR_WY = 4e-2, 4e-2 18 | tc.BEAM_WX, tc.BEAM_WY = 8e-2, 8e-2 19 | tc.OBJECT_PHASE_INPUT, tc.OBJECT_AMPLITUDE_INPUT = True, False 20 | tc.MASK_PHASE_MODULATION, tc.MASK_AMPLITUDE_MODULATION = True, True 21 | tc.MASK_INIT_TYPE = 'const' 22 | tc.MASK_NUMBER = 5 23 | tc.OBJECT_MASK_DISTANCE, tc.MASK_MASK_DISTANCE, tc.MASK_SENSOR_DISTANCE = 3e-3, 3e-3, 3e-3 24 | tc.THETA0 = 75.0 25 | tc.DATA_ROW, tc.DATA_COL, tc.NUM_CLASS = 28, 28, 10 26 | tc.CLASS_SIZE_X, tc.CLASS_SIZE_Y, tc.CLASS_NUM_X, tc.CLASS_NUM_Y = 4.8e-3, 4.8e-3, 10, 10 27 | tc.NUM_HOLES = 10 28 | tc.TRAINING_DATA_TYPE, tc.TESTING_DATA_TYPE = 'fashion-mnist', 'fashion-mnist' 29 | tc.NUMBER_TRAINING_ELEMENTS, tc.NUMBER_TEST_ELEMENTS = 60000, 10000 30 | tc.BATCH_SIZE, tc.TEST_BATCH_SIZE = 64, 20 31 | tc.LEARNING_RATE, tc.OPTIMIZER, tc.TV_LOSS_PARAM = 1e-3, 'adam', 0.0 32 | tc.MAX_EPOCH = 50 33 | tc.TFBOARD_PATH, tc.MASK_SAVING_PATH, tc.MASK_TESTING_PATH, tc.OUTPUT_PATH = '.\TFBOARD', \ 34 | '.\MODEL\MASKS', '.\BEST_MODEL', '.\OUTPUT' 35 | tc.DATA_PATH = 'D:\Deniz\Python\Datasets' 36 | tc.validation_ratio = 0.5 # Ratio of number of elements in validation set to test set 37 | 38 | # COMPUTED GLOBAL PARAMETERS 39 | tc.WX = tc.M*tc.DX 40 | tc.WY = tc.N*tc.DY 41 | tc.OBJECT_ROW = int(np.round(tc.OBJ_WX/tc.DX)) 42 | tc.OBJECT_COL = int(np.round(tc.OBJ_WY/tc.DY)) 43 | tc.MASK_ROW = int(np.round(tc.MASK_WX/tc.DX)) 44 | tc.MASK_COL = int(np.round(tc.MASK_WY/tc.DY)) 45 | tc.SENSOR_ROW = int(np.round(tc.SENSOR_WX/tc.DX)) 46 | tc.SENSOR_COL = int(np.round(tc.SENSOR_WY/tc.DY)) 47 | tc.BEAM_ROW = int(np.round(tc.BEAM_WX/tc.DX)) 48 | tc.BEAM_COL = int(np.round(tc.BEAM_WY/tc.DY)) 49 | 50 | return tc -------------------------------------------------------------------------------- /mask_modulation_model.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Mask Modulation Model 3 | ''' 4 | 5 | import tensorflow as tf 6 | import os 7 | import numpy as np 8 | import tf_OpticsModule as tom 9 | import initialization as init 10 | 11 | tc = init.init_params() 12 | 13 | def leakyRelu(x, alpha=0.1): 14 | return tf.nn.relu(x) - alpha * tf.nn.relu(-x) 15 | 16 | def read_mask(path, L, mask_type): 17 | 18 | ''' 19 | path : Path to the folder containing the trained masks to be loaded 20 | L : Layer number OR Mask number from 0 to MASK_NUMBER-1 21 | ''' 22 | mask_list = os.listdir(path) 23 | if mask_type == 'amplitude': 24 | mask = np.loadtxt(path + "/" + mask_list[L]) 25 | elif mask_type == 'phase': 26 | mask = np.loadtxt(path + "/" + mask_list[tc.MASK_NUMBER+L]) 27 | mask = tf.cast(mask, tf.float32) 28 | return mask 29 | 30 | def mask_init(masknum): 31 | 32 | if tc.MASK_PHASE_MODULATION is True: 33 | if tc.MASK_INIT_TYPE == 'const': 34 | mask_phase_org = tf.get_variable('mask_phase' + str(masknum), initializer=tf.constant(1.0, shape=[tc.MASK_ROW, tc.MASK_COL])) 35 | mask_phase = mask_phase_org * 2 * np.pi 36 | elif tc.MASK_INIT_TYPE == 'random': 37 | mask_phase_org = tf.get_variable('mask_phase' + str(masknum), initializer=tf.random_uniform(shape=[tc.MASK_ROW, tc.MASK_COL],minval=0.5,maxval=1.5)) 38 | mask_phase = mask_phase_org * 2 * np.pi 39 | elif tc.MASK_INIT_TYPE == 'trained': 40 | mask_phase = read_mask(tc.MASK_PATH, masknum, 'phase') 41 | else: 42 | mask_phase = tf.zeros([tc.MASK_ROW, tc.MASK_COL]) 43 | 44 | if tc.MASK_AMPLITUDE_MODULATION is True: 45 | if tc.MASK_INIT_TYPE == 'trained': 46 | mask_amp = read_mask(tc.MASK_PATH, masknum, 'amplitude') 47 | else: 48 | mask_amp_org = tf.get_variable('mask_amp' + str(masknum), initializer=tf.constant(1.0, shape=[tc.MASK_ROW, tc.MASK_COL])) 49 | mask_amp = tf.nn.relu(mask_amp_org) 50 | else: 51 | mask_amp = tf.ones([tc.MASK_ROW, tc.MASK_COL]) 52 | 53 | pad_X = int(tc.M//2-tc.MASK_ROW//2) 54 | pad_Y = int(tc.N//2-tc.MASK_COL//2) 55 | paddings = tf.constant([[pad_X,pad_X],[pad_Y,pad_Y]]) 56 | mask_phase = tf.pad(mask_phase,paddings) 57 | mask_amp = tf.pad(mask_amp,paddings) 58 | 59 | return mask_phase, mask_amp 60 | 61 | def detector_plane(measurement,cell_locs,thecell): 62 | 63 | cell_locs[:,0] = cell_locs[:,0]+tc.M//2-tc.SENSOR_ROW//2 64 | cell_locs[:,1] = cell_locs[:,1]+tc.N//2-tc.SENSOR_COL//2 65 | kk = 0 66 | ulcorner = cell_locs[kk,0:2] 67 | probs = tf.reduce_mean(tf.slice(measurement,[0,ulcorner[0],ulcorner[1]],[tc.BATCH_SIZE,thecell.shape[0],thecell.shape[1]]),axis=[1,2]) 68 | class_probs = tf.expand_dims(probs,-1) 69 | for kk in range(1,cell_locs.shape[0]): 70 | ulcorner = cell_locs[kk,0:2] 71 | probs = tf.reduce_mean(tf.slice(measurement,[0,ulcorner[0],ulcorner[1]],[tc.BATCH_SIZE,thecell.shape[0],thecell.shape[1]]),axis=[1,2]) 72 | probs = tf.expand_dims(probs,-1) 73 | class_probs = tf.concat([class_probs,probs],axis=1) 74 | 75 | # leakage = tf.divide(tf.reduce_mean(class_probs,axis=1),tf.reduce_mean(measurement,axis=[1,2])) 76 | E = tf.expand_dims(tf.reduce_mean(measurement,axis=[1,2]), -1) 77 | S = tf.expand_dims(tf.reduce_mean(class_probs,axis=1), -1) 78 | C = tf.divide(E-S, E) 79 | S = tf.divide(S, E) 80 | leakage = tf.concat([C,S],axis=1) 81 | return class_probs, leakage 82 | 83 | def inference(field): 84 | 85 | # First Layer 86 | with tf.name_scope('hidden1'): 87 | 88 | with tf.name_scope('propagation'): 89 | img_p = tom.batch_propagate(field, tc.WLENGTH, tc.OBJECT_MASK_DISTANCE, tc.DX, tc.DY, 1.0, tc.THETA0) 90 | 91 | with tf.name_scope('mask'): 92 | mask_phase, mask_amp = mask_init(0) 93 | mask_amp = tf.divide(mask_amp,tf.reduce_max(tf.abs(mask_amp))) 94 | #------------------------------------------------------------------ 95 | mask = tf.complex(mask_amp * tf.cos(mask_phase), mask_amp * tf.sin(mask_phase)) 96 | save_mask_phase = tf.expand_dims(mask_phase,0) 97 | save_mask_amp = tf.expand_dims(mask_amp,0) 98 | 99 | hidden = tf.multiply(img_p, mask) 100 | 101 | # Middle Layers 102 | for layer_num in range(2, tc.MASK_NUMBER + 1): 103 | with tf.name_scope('hidden' + str(layer_num)): 104 | 105 | with tf.name_scope('propagation'): 106 | img_p = tom.batch_propagate(hidden, tc.WLENGTH, tc.MASK_MASK_DISTANCE, tc.DX, tc.DY, 1.0, tc.THETA0) 107 | 108 | with tf.name_scope('mask'): 109 | mask_phase, mask_amp = mask_init(layer_num-1) 110 | mask_amp = tf.divide(mask_amp,tf.reduce_max(tf.abs(mask_amp))) 111 | #------------------------------------------------------------------ 112 | mask = tf.complex(mask_amp* tf.cos(mask_phase), mask_amp * tf.sin(mask_phase)) 113 | save_mask_phase = tf.concat([save_mask_phase, tf.expand_dims(mask_phase,0)], 0) 114 | save_mask_amp = tf.concat([save_mask_amp, tf.expand_dims(mask_amp,0)], 0) 115 | 116 | hidden = tf.multiply(img_p, mask) 117 | 118 | # Last Layer 119 | with tf.name_scope('last'): 120 | 121 | with tf.name_scope('propagation'): 122 | img_p = tom.batch_propagate(hidden, tc.WLENGTH, tc.MASK_SENSOR_DISTANCE, tc.DX, tc.DY, 1.0, tc.THETA0) 123 | 124 | with tf.name_scope('sensor'): 125 | measurement = tf.square(tf.abs(img_p)) 126 | 127 | with tf.name_scope('Hybrid'): 128 | 129 | measurement_cnn = tf.reshape(measurement, [tc.BATCH_SIZE, tc.M, tc.N]) 130 | measurement_cnn = tf.layers.batch_normalization(measurement_cnn) 131 | roi = tf.slice(measurement_cnn,[0,tc.M//2-100//2,tc.N//2-100//2],[tc.BATCH_SIZE,100,100]) 132 | sensor_mean, sensor_variance = tf.nn.moments(roi,axes=[1,2],keep_dims=True) 133 | roi = tf.divide(roi-sensor_mean,tf.sqrt(sensor_variance)) 134 | # measurement_cnn = tf.reshape(measurement, [BATCH_SIZE, MASK_COL, MASK_ROW]) 135 | measurement_cnn = tf.expand_dims(roi,-1) 136 | measurement_cnn = tf.nn.avg_pool(value=measurement_cnn, ksize=[1,10,10,1], strides=[1,10,10,1], padding='VALID') 137 | fc0 = tf.layers.flatten(measurement_cnn) 138 | fc0 = tf.layers.dropout(fc0, training='train'==tf.estimator.ModeKeys.TRAIN) 139 | logits = tf.layers.dense(inputs=fc0, units=10) 140 | # logits, sensor_leakage = detector_plane(measurement,cell_locs,thecell) 141 | 142 | return measurement, save_mask_phase, save_mask_amp, logits 143 | 144 | def loss_function(self, ground_truth, object_data): 145 | 146 | # #BUCKET LOSS 147 | # self = tf.divide(self,tf.reduce_sum(self,-1,keep_dims=True)) 148 | # self_64 = tf.cast(self, dtype=tf.float64) 149 | # loss_ = tf.reduce_mean(tf.square(1-tf.reduce_sum(tf.multiply(self_64,ground_truth),-1))) 150 | 151 | # NORMALIZED MSE LOSS 152 | # corr = tf.reduce_sum(tf.multiply(self,ground_truth)) 153 | # autoCorrIn = tf.reduce_sum(tf.multiply(self,self)) 154 | # # autoCorrGT = tf.reduce_sum(tf.multiply(ground_truth,ground_truth)) 155 | # scaling_factor = tf.divide(corr,autoCorrIn) 156 | # self = tf.multiply(self,scaling_factor) 157 | # squared_deltas = tf.square(self - ground_truth) 158 | # loss = tf.reduce_sum(squared_deltas, reduction_indices=[1,2]) 159 | # loss_ = tf.reduce_mean(loss, name='mse') 160 | 161 | #UNITARY MSE LOSS 162 | # energyratio = tf.divide(tf.reduce_sum(tf.square(tf.abs(ground_truth))),tf.reduce_sum(self)) 163 | # ground_truth = tf.multiply(self,energyratio) 164 | # squared_deltas = tf.square(self - ground_truth) 165 | # loss = tf.reduce_sum(squared_deltas, reduction_indices=[1]) 166 | # loss_ = tf.reduce_mean(loss, name='mse') 167 | 168 | #LEAKAGE LOSS 169 | # squared_delta_leak = tf.reduce_sum(tf.square(leakage),reduction_indices=[2]) 170 | # leak_loss = tf.reduce_mean(squared_delta_leak,reduction_indices=[1]) 171 | 172 | #loss_ = tf.cond((step*BATCH_SIZE)<(NUMBER_TRAINING_ELEMENTS*0), lambda: tf.add(loss_, tf.norm(leak_loss,name='light_leakage')), lambda: loss_) 173 | # tf.summary.scalar('loss', loss_) 174 | # Cross entropy 175 | loss_ = tf.losses.sparse_softmax_cross_entropy(labels=ground_truth, logits=self) 176 | 177 | return loss_ 178 | 179 | def tv_loss_function(measurement): 180 | 181 | pixel_dif1 = tf.subtract(measurement[:, 1:, :], measurement[:, :-1, :]) 182 | pixel_dif2 = tf.subtract(measurement[:, :, 1:], measurement[:, :, :-1]) 183 | sum_axis = [1, 2] 184 | tot_var = (tf.reduce_sum(tf.abs(pixel_dif1), axis=sum_axis) + 185 | tf.reduce_sum(tf.abs(pixel_dif2), axis=sum_axis)) 186 | tot_var_mean = tf.reduce_mean(tot_var, name='tv') 187 | 188 | return tot_var_mean 189 | 190 | 191 | def training(loss): 192 | 193 | ONN_variable = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'mask') 194 | DNN_variable = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'conv') + tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'dense') 195 | extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS) 196 | 197 | if tc.OPTIMIZER == 'gradient': 198 | optimizer = tf.train.GradientDescentOptimizer(tc.LEARNING_RATE) 199 | elif tc.OPTIMIZER == 'adam': 200 | optimizer_ONN = tf.train.AdamOptimizer(tc.LEARNING_RATE * 10) 201 | optimizer_DNN = tf.train.AdamOptimizer(tc.LEARNING_RATE * 0.1) 202 | else: 203 | pass 204 | train_op = tf.group([optimizer_ONN.minimize(loss, var_list=ONN_variable), optimizer_DNN.minimize(loss, var_list=DNN_variable), extra_update_ops]) 205 | 206 | return train_op 207 | 208 | 209 | def reset_ONN(): 210 | 211 | target_op = [] 212 | 213 | train_vars = tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, 'mask') 214 | 215 | if tc.MASK_AMPLITUDE_MODULATION is True: 216 | 217 | for num in range(tc.MASK_NUMBER): 218 | 219 | if tc.MASK_PHASE_MODULATION is True: 220 | 221 | if tc.MASK_INIT_TYPE == 'const': 222 | op1 = train_vars[2 * num].assign(tf.constant(1.0, shape=[tc.MASK_ROW, tc.MASK_COL])) 223 | elif tc.MASK_INIT_TYPE == 'random': 224 | op1 = train_vars[2 * num].assign(tf.random_uniform(shape=[tc.MASK_ROW, tc.MASK_COL],minval=0.5,maxval=1.5)) 225 | 226 | target_op = tf.group(target_op, op1) 227 | # elif tc.MASK_INIT_TYPE == 'trained': 228 | # mask_phase = read_mask(tc.MASK_PATH, masknum, 'phase') 229 | # else: 230 | # mask_phase = tf.zeros([tc.MASK_ROW, tc.MASK_COL]) 231 | 232 | if tc.MASK_AMPLITUDE_MODULATION is True: 233 | # if tc.MASK_INIT_TYPE == 'trained': 234 | # mask_amp = read_mask(tc.MASK_PATH, masknum, 'amplitude') 235 | # else: 236 | op2 = train_vars[2 * num + 1].assign(tf.constant(1.0, shape=[tc.MASK_ROW, tc.MASK_COL])) 237 | 238 | target_op = tf.group(target_op, op2) 239 | # else: 240 | # mask_amp = tf.ones([tc.MASK_ROW, tc.MASK_COL]) 241 | 242 | else: 243 | 244 | for num in range(tc.MASK_NUMBER): 245 | 246 | if tc.MASK_INIT_TYPE == 'const': 247 | train_vars[num].assign(tf.constant(1.0, shape=[tc.MASK_ROW, tc.MASK_COL])) 248 | elif tc.MASK_INIT_TYPE == 'random': 249 | train_vars[num].assign(tf.random_uniform(shape=[tc.MASK_ROW, tc.MASK_COL],minval=0.5,maxval=1.5)) 250 | 251 | return target_op -------------------------------------------------------------------------------- /onn_mask_testing.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on Sun Jul 1 11:04:13 2018 4 | 5 | @author: deepLearning505 6 | """ 7 | 8 | #import clc 9 | #clc.clear_all() 10 | 11 | import tensorflow as tf 12 | import numpy as np 13 | import matplotlib.pyplot as plt 14 | import mask_modulation_model as mmm 15 | import initialization as init 16 | import data_generation as dtg 17 | 18 | dict = init.import_parameters('./PARAMETERS.txt') 19 | APPLICATION = (dict['application']) 20 | WLENGTH = float(dict['wavelength']) 21 | REF_IDX = float(dict['ref_idx']) 22 | M = int(dict['window_size_X']) 23 | N = int(dict['window_size_Y']) 24 | DX = float(dict['pixel_size_X']) 25 | DY = float(dict['pixel_size_Y']) 26 | MASK_WX = float(dict['mask_width_X']) 27 | MASK_WY = float(dict['mask_width_Y']) 28 | OBJECT_WX = float(dict['object_width_X']) 29 | OBJECT_WY = float(dict['object_width_Y']) 30 | SENSOR_WX = float(dict['sensor_width_X']) 31 | SENSOR_WY = float(dict['sensor_width_Y']) 32 | SENSOR_DX = float(dict['sensor_pixelsize_X']) 33 | SENSOR_DY = float(dict['sensor_pixelsize_Y']) 34 | OBJECT_PHASE_INPUT = bool(int(dict['object_phase_input'])) 35 | OBJECT_AMPLITUDE_INPUT = bool(int(dict['object_amplitude_input'])) 36 | MASK_PHASE_MODULATION = bool(int(dict['mask_phase_modulation'])) 37 | MASK_AMPLITUDE_MODULATION = bool(int(dict['mask_amplitude_modulation'])) 38 | MASK_INIT_TYPE = (dict['mask_init_type']) 39 | MASK_PHASE_INIT_VALUE = float(dict['mask_phase_init_value']) 40 | MASK_AMP_INIT_VALUE = float(dict['mask_amp_init_value']) 41 | MASK_NUMBER = int(float(dict['mask_number'])) 42 | OBJECT_MASK_DISTANCE = float(dict['object_mask_distance']) 43 | MASK_MASK_DISTANCE = float(dict['mask_mask_distance']) 44 | MASK_SENSOR_DISTANCE = float(dict['mask_sensor_distance']) 45 | NUM_CLASS = int(dict['number_of_classes']) 46 | LABEL_CELL_to_SENSOR_X = float(dict['sensorplane_cell2sensor_X']) 47 | LABEL_CELL_to_SENSOR_Y = float(dict['sensorplane_cell2sensor_Y']) 48 | DATA_ROW = int(dict['number_of_rows_data']) 49 | DATA_COL = int(dict['number_of_cols_data']) 50 | NUM_HOLES = int(dict['number_of_holes']) 51 | 52 | TRAINING_DATA_TYPE = (dict['training_data_type']) 53 | TESTING_DATA_TYPE = (dict['testing_data_type']) 54 | OBJECT_DATA_PATH = (dict['object_data_path']) 55 | LEARNING_RATE = float(dict['learning_rate']) 56 | MAX_STEPS = int(dict['max_steps']) 57 | TV_WEIGHT = float(dict['total_variation_loss_param']) 58 | BATCH_SIZE = int(dict['batch_size']) 59 | TEST_STEPS = int(dict['test_steps']) 60 | OPTIMIZER = (dict['optimizer']) 61 | TENSORBOARD_PATH = (dict['tensorboard_path']) 62 | MASK_SAVING_PATH = (dict['mask_saving_path']) 63 | MASK_TESTING_PATH = (dict['mask_testing_path']) #!!!!! THE ONLY DIFFERENCE from TRAINING PARAMS 64 | SENSOR_SAVING_PATH = (dict['sensor_saving_path']) 65 | INPUT_SAVING_PATH = (dict['input_saving_path']) 66 | 67 | WX = M*DX 68 | WY = N*DY 69 | WINDOW_PIXEL_NUM = M*N 70 | OBJECT_ROW = int(np.floor(OBJECT_WX/DX)) 71 | OBJECT_COL = int(np.floor(OBJECT_WY/DY)) 72 | OBJECT_PIXEL_NUM = OBJECT_ROW*OBJECT_COL 73 | DATA_PIXEL_NUM = DATA_ROW*DATA_COL 74 | MASK_ROW = int(np.floor(MASK_WX/DX)) 75 | MASK_COL = int(np.floor(MASK_WY/DY)) 76 | MASK_PIXEL_NUM = MASK_ROW * MASK_COL 77 | SENSOR_ROW = int(np.floor(SENSOR_WX/SENSOR_DX)) 78 | SENSOR_COL = int(np.floor(SENSOR_WY/SENSOR_DY)) 79 | SENSOR_PIXEL_NUM = SENSOR_ROW*SENSOR_COL 80 | BATCH_SHAPE = [BATCH_SIZE, M, N] 81 | 82 | cell_locs,celltype1,celltype2 = dtg.sensorplane_geometry() 83 | 84 | if __name__ == '__main__': 85 | 86 | save_mask_phase, save_mask_amp, save_mask_holes = mmm.read_mask(MASK_TESTING_PATH) 87 | #save_mask_amp[save_mask_amp == 0] = 0.031 88 | 89 | placeholder_input = tf.placeholder(tf.complex64, shape=(BATCH_SIZE, WINDOW_PIXEL_NUM)) 90 | 91 | onn_measurement = mmm.inference_testing(placeholder_input, save_mask_phase, save_mask_amp, save_mask_holes) 92 | 93 | # tf.gfile.MakeDirs(SENSOR_SAVING_PATH) 94 | 95 | sess = tf.InteractiveSession() 96 | 97 | count = 0 98 | 99 | for step in range(MAX_STEPS): 100 | 101 | testing_input, testing_gt, testing_gt_1 = dtg.generate_data('testing') 102 | onn_measurement_value_test = sess.run(onn_measurement, feed_dict={placeholder_input: testing_input}) 103 | 104 | save_measurement = np.reshape(onn_measurement_value_test, (M, N)) 105 | if(OBJECT_AMPLITUDE_INPUT): 106 | 107 | save_input = np.reshape(np.real(testing_input), (M, N)) 108 | 109 | else: 110 | 111 | save_input = (np.reshape(np.angle(testing_input), (M, N))+np.pi)/2/np.pi 112 | 113 | save_input = save_input[M//2-OBJECT_ROW//2:M//2-OBJECT_ROW//2+OBJECT_ROW,\ 114 | N//2-OBJECT_COL//2:N//2-OBJECT_COL//2+OBJECT_COL] 115 | plt.imsave(SENSOR_SAVING_PATH + "/test_intensity_" + str(step) + ".bmp", save_measurement, cmap='gray') 116 | plt.imsave(INPUT_SAVING_PATH + "/test_intensity_" + str(step) + ".bmp", save_input, cmap='gray') 117 | #COMPARISON AGAINST OTHER CLASS LABELS 118 | save_measurement = save_measurement[M//2-SENSOR_ROW//2:M//2-SENSOR_ROW//2+SENSOR_ROW,\ 119 | N//2-SENSOR_COL//2:N//2-SENSOR_COL//2+SENSOR_COL] 120 | class_probs = np.zeros(NUM_CLASS) 121 | for kk in range(NUM_CLASS): 122 | ulcorner = cell_locs[kk,0:2] 123 | ctype = cell_locs[kk,2] 124 | if(ctype==1): 125 | class_probs[kk] = np.mean(save_measurement[ulcorner[0]:ulcorner[0]+celltype1.shape[0],\ 126 | ulcorner[1]:ulcorner[1]+celltype1.shape[1]]) 127 | else: 128 | class_probs[kk] = np.mean(save_measurement[ulcorner[0]:ulcorner[0]+celltype2.shape[0],\ 129 | ulcorner[1]:ulcorner[1]+celltype2.shape[1]]) 130 | 131 | if(np.argmax(class_probs)==np.argmax(testing_gt_1)): 132 | count = count+1 133 | # print('count is',count) 134 | 135 | accuracy = count / MAX_STEPS 136 | print('accuracy is', accuracy) -------------------------------------------------------------------------------- /onn_mask_train.py: -------------------------------------------------------------------------------- 1 | ''' 2 | MAIN TRAINING CODE 3 | ''' 4 | import tensorflow as tf 5 | import numpy as np 6 | import matplotlib.pyplot as plt 7 | import mask_modulation_model as mmm 8 | import data_generation as dtg 9 | import data_ops as dto 10 | import initialization as init 11 | from datetime import datetime 12 | import os 13 | import scipy.io as sio 14 | os.environ["CUDA_DEVICE_ORDER"]="PCI_BUS_ID" 15 | os.environ["CUDA_VISIBLE_DEVICES"]="0" 16 | 17 | # IMPORT and GLOBALIZE PARAMETERS 18 | tc = init.init_params() 19 | 20 | #GPU-COMPUTING CONFIGURATION 21 | def get_default_config(fraction=0.9): 22 | 23 | conf = tf.ConfigProto() 24 | conf.gpu_options.per_process_gpu_memory_fraction = fraction 25 | conf.gpu_options.allocator_type = 'BFC' 26 | conf.gpu_options.allow_growth = True 27 | conf.allow_soft_placement = True 28 | 29 | return conf 30 | tf.gfile.MakeDirs(tc.OUTPUT_PATH) 31 | tf.gfile.MakeDirs(tc.MASK_SAVING_PATH) 32 | tf.gfile.MakeDirs(tc.MASK_TESTING_PATH) 33 | 34 | # cell_locs, thecell, label_fields, det_distribution = dto.sensorplane_geometry() 35 | 36 | # List of monitoring variables 37 | global_step = 0 38 | #accuracy_train 39 | #accuracy_test 40 | #total_loss_train 41 | #mean_loss_train 42 | #total_loss_test 43 | #mean_loss_test 44 | #hit_count 45 | best_loss = 1e12 46 | best_accuracy = 0 47 | 48 | # LOG FILE 49 | text_file = open("LOG.txt", 'w') 50 | msg = "epoch " + "mean_train_loss " + "mean_test_loss " + "training_accuracy " + "testing_accuracy " 51 | text_file.write(msg + '\n') 52 | 53 | if __name__ == '__main__': 54 | 55 | conf = get_default_config() 56 | sess = tf.InteractiveSession(config=conf) 57 | 58 | with tf.name_scope("datasets"): 59 | # DEFINE DATA PIPELINE, INITIALIZE ITERATOR 60 | batch_train = dtg.get_data_batch('training') 61 | batch_test = dtg.get_data_batch('validation') 62 | batch_final = dtg.get_data_batch('testing') 63 | # DEFINE THE ITERATOR 64 | iterator = tf.data.Iterator.from_structure(batch_train.output_types, batch_train.output_shapes) 65 | # iterator: tf.data.Iterator = tf.data.Iterator.from_structure(batch_train.output_types, batch_train.output_shapes) 66 | batch = iterator.get_next() 67 | data_amp, data_phase, sensor_gt, data_label = batch 68 | onn_field = tf.complex(data_amp * tf.cos(data_phase), data_amp * tf.sin(data_phase)) 69 | 70 | # DEFINE THE MODEL 71 | onn_measurement, onn_mask_phase, onn_mask_amp, onn_logits = mmm.inference(onn_field) 72 | onn_loss = mmm.loss_function(onn_logits, tf.cast(data_label,dtype=tf.int64), onn_field) 73 | onn_predictions = tf.nn.softmax(onn_logits, name = 'predictions') 74 | onn_hit = tf.reduce_sum(tf.cast(tf.equal(tf.cast(data_label,dtype=tf.int64), tf.argmax(onn_predictions, axis=1)),dtype=tf.int64)) 75 | onn_tv_loss = mmm.tv_loss_function(onn_measurement) 76 | onn_combine_loss = onn_loss + tc.TV_LOSS_PARAM * onn_tv_loss 77 | onn_train = mmm.training(onn_combine_loss) 78 | 79 | reset_op = mmm.reset_ONN() 80 | 81 | # accuracy, accuracy_op = tf.metrics.accuracy(tf.argmax(data_label, axis=1), tf.argmax(onn_predictions, axis=1)) 82 | # mean_loss, mean_loss_op = tf.metrics.mean(onn_loss) 83 | 84 | init_all = tf.group(tf.global_variables_initializer(), 85 | tf.local_variables_initializer()) 86 | saver = tf.train.Saver() 87 | sess.run(init_all) 88 | # sess.graph.finalize() 89 | print("Entering training loop") 90 | 91 | for epoch in range(1,tc.MAX_EPOCH+1): 92 | 93 | # Initialize iterator and shuffle data 94 | # train_data = batch_train.shuffle(tc.NUMBER_TRAINING_ELEMENTS) 95 | sess.run(iterator.make_initializer(batch_train)) 96 | train_step = input_count = hit_count_train = total_loss_train = 0 97 | while True: 98 | try: 99 | # run train iteration 100 | _, onn_loss_value, onn_mask_phase_value, onn_mask_amp_value, onn_predictions_value, hit_count, input_field = sess.run([onn_train, 101 | onn_combine_loss, 102 | onn_mask_phase, onn_mask_amp, 103 | onn_predictions, onn_hit, 104 | onn_field]) 105 | # print(input_field.shape) 106 | # exit() 107 | 108 | train_step += 1 109 | global_step += 1 110 | input_count += tc.BATCH_SIZE 111 | hit_count_train += hit_count 112 | total_loss_train += onn_loss_value 113 | if(train_step==1): 114 | first_input = input_field[0,:,:] 115 | first_input_phase = np.angle(first_input) 116 | first_input_amp = np.abs(first_input) 117 | plt.imsave("./first_input_amp" + ".png", first_input_amp, cmap='gray') 118 | plt.imsave("./first_input_phase" + ".png", first_input_phase, cmap='gray') 119 | 120 | except (tf.errors.OutOfRangeError, StopIteration): 121 | break 122 | 123 | accuracy_train = hit_count_train/input_count*100 124 | mean_loss_train = total_loss_train/train_step 125 | # initialize iterator for validation dataset. No need to shuffle 126 | sess.run(iterator.make_initializer(batch_test)) 127 | test_step = test_count = hit_count_test = total_loss_test = 0 128 | while True: 129 | try: 130 | # run test iteration 131 | onn_loss_value_test, onn_measurement_value_test, test_field, hit_count = sess.run([onn_combine_loss, onn_measurement, onn_field, onn_hit]) 132 | 133 | test_step += 1 134 | test_count += tc.BATCH_SIZE 135 | hit_count_test += hit_count 136 | total_loss_test += onn_loss_value_test 137 | except (tf.errors.OutOfRangeError, StopIteration): 138 | break 139 | 140 | accuracy_test = hit_count_test/test_count*100 141 | mean_loss_test = total_loss_test/test_step 142 | #Log/Record 143 | msg = "epoch " + "mean_train_loss " + "mean_test_loss " + "training_accuracy " + "testing_accuracy " + str(datetime.now()) 144 | print(msg) 145 | msg = str(epoch) + " " + str(mean_loss_train) + " " + str(mean_loss_test) + " " + str(accuracy_train) + " " + str(accuracy_test) 146 | print(msg) 147 | text_file.write(msg + '\n') 148 | 149 | plt.imsave(tc.OUTPUT_PATH + "/SensPlInt_" + str(epoch) + ".png", onn_measurement_value_test[0,:,:], cmap='gray') 150 | plt.imsave(tc.OUTPUT_PATH + "/TestInput_" + str(epoch) + ".png", np.angle(test_field[0,:,:]), cmap='gray') 151 | 152 | if tc.APPLICATION == 'classification': 153 | save_model = bool(accuracy_test>best_accuracy) 154 | elif tc.APPLICATION == 'amplitude_imaging': 155 | save_model = bool(mean_loss_test wavelength of the optical signal 214 | f -> 2-by-1 list contains -> focal length in x and focal length in y 215 | center -> 2-by-1 list contains -> central shift of whole lens func. in x and y 216 | fshift -> lateral off-axis shift on the focal plane 217 | dia -> diameter of lens aperture 218 | dx,dy -> sampling intervals in space 219 | M,N -> size of simulation window 220 | 221 | OUTPUTS: 222 | lensfunc -> numerical lensfunction defined in space 223 | 224 | """ 225 | x = (np.arange(M)-(M-1)/2)*dx 226 | y = (np.arange(N)-(N-1)/2)*dy 227 | x0,y0 = center[0], center[1] 228 | xf,yf = fshift[0], fshift[1] 229 | Lxy2 = (np.outer((x-x0)**2,np.ones(N))+np.outer(np.ones(M),(y-y0)**2)) 230 | D = Lxy2<=(diameter**2) 231 | sq = np.outer((x-xf)**2,np.ones(N))+np.outer(np.ones(M),(y-yf)**2); 232 | lensfunc = np.exp(-1j*2*np.pi/wlength*sq/2/focal_length)*D; 233 | lensfunc = tf.convert_to_tensor(lensfunc, dtype=tf.complex64) 234 | lensfunc = tf.reshape(lensfunc,shape=[1,M*N],name='lens') 235 | return lensfunc 236 | 237 | def ideallens(wlength,focal_length,center,fshift,diameter,dx,dy,M,N): 238 | 239 | """ 240 | Create function of a ideal paraxial lens 241 | INPUTS : 242 | wlength -> wavelength of the optical signal 243 | f -> 2-by-1 list contains -> focal length in x and focal length in y 244 | center -> 2-by-1 list contains -> central shift of whole lens func. in x and y 245 | fshift -> lateral off-axis shift on the focal plane 246 | dia -> diameter of lens aperture 247 | dx,dy -> sampling intervals in space 248 | M,N -> size of simulation window 249 | 250 | OUTPUTS: 251 | lensfunc -> numerical lensfunction defined in space 252 | 253 | """ 254 | x = (np.arange(M)-(M-1)/2)*dx 255 | y = (np.arange(N)-(N-1)/2)*dy 256 | x0,y0 = center[0], center[1] 257 | xf,yf = fshift[0], fshift[1] 258 | Lxy2 = (np.outer((x-x0)**2,np.ones(N))+np.outer(np.ones(M),(y-y0)**2)) 259 | D = Lxy2<=(diameter**2) 260 | D = np.astype('int') 261 | sq = np.outer((x-xf)**2,np.ones(N))+np.outer(np.ones(M),(y-yf)**2); 262 | R= (sq+focal_length**2)**(0.5) 263 | lensfunc = np.exp(-1j*2*np.pi/wlength*R)*D; 264 | lensfunc = tf.convert_to_tensor(lensfunc, dtype=tf.complex64) 265 | lensfunc = tf.reshape(lensfunc,shape=[1,M*N],name='lens') 266 | return lensfunc 267 | 268 | def batch_propagate(field, wlength, z, dx, dy, refidx,*theta0): 269 | 270 | if theta0: 271 | prop_field = tf_FSPAS_FFT(field, wlength, z, dx, dy, refidx,theta0) 272 | else: 273 | prop_field = tf_FSPAS_FFT(field, wlength, z, dx, dy, refidx) 274 | # img_prop, H = tf_FSPAS(img_reshaped[0, :, :], wlength, z, dx, dy, refidx) 275 | # img_prop_cat = tf.expand_dims(img_prop, 0) 276 | # for i in range(1, batch_shape[0]): 277 | # img_prop, H = tf_FSPAS(img_reshaped[i, :, :], wlength, z, dx, dy, refidx) 278 | # img_prop = tf.expand_dims(img_prop, 0) 279 | # img_prop_cat = tf.concat([img_prop_cat, img_prop], 0) 280 | # 281 | # img_prop_reshaped = tf.reshape(img_prop_cat, [batch_shape[0], batch_shape[1]*batch_shape[2]]) 282 | # img_prop_reshaped = tf.reshape(img_prop, [batch_shape[0], batch_shape[1]*batch_shape[2]]) 283 | 284 | return prop_field -------------------------------------------------------------------------------- /virtual_networks.py: -------------------------------------------------------------------------------- 1 | # -*- coding:UTF-8 -*- 2 | 3 | import collections 4 | import tensorflow as tf 5 | from tensorflow.contrib.layers import flatten 6 | slim = tf.contrib.slim 7 | 8 | 9 | class Block(collections.namedtuple('Block', ['scope', 'unit_fn', 'args'])): 10 | ''' 11 | collections.namedtuple ResNet block named tuple, 12 | Block: 13 | scope: Block 14 | unit_fn:ResNet V2 15 | args: block[(depth, depth_bottleneck, stride)] 16 | :Block('block1', bottleneck, [(256,64,1),(256,64,1),(256,64,2)]) 17 | ''' 18 | 19 | def subsample(inputs, factor, scope=None): 20 | if factor == 1: 21 | return inputs 22 | else: 23 | return slim.max_pool2d(inputs, [1, 1], stride=factor, scope=scope) 24 | 25 | def conv2d_same(inputs, num_outputs, kernel_size, stride, scope=None): 26 | """ 27 | if stride>1, then we do explicit zero-padding, followed by conv2d with 'VALID' padding 28 | """ 29 | if stride == 1: 30 | return slim.conv2d(inputs, num_outputs, kernel_size, stride=1, padding='SAME', scope=scope) 31 | else: 32 | pad_total = kernel_size - 1 33 | pad_beg = pad_total // 2 34 | pad_end = pad_total - pad_beg 35 | inputs = tf.pad(inputs, [[0, 0], [pad_beg, pad_end], [pad_beg, pad_end], [0, 0]]) 36 | return slim.conv2d(inputs, num_outputs, kernel_size, stride=stride, padding='VALID', scope=scope) 37 | 38 | 39 | #---------------------Blocks------------------- 40 | @slim.add_arg_scope 41 | def stack_blocks_dense(net, blocks, outputs_collections=None): 42 | """ 43 | Args: 44 | net: A Tensor of size [batch, height, width, channels].inputs 45 | blocks: 是之前定义的Block的class的列表。 46 | outputs_collections: 收集各个end_points的collections 47 | Returns: 48 | net: Output tensor 49 | """ 50 | # 循环Block类对象的列表blocks,即逐个Residual Unit地堆叠 51 | for block in blocks: 52 | with tf.variable_scope(block.scope, 'block', [net]) as sc: 53 | for i, unit in enumerate(block.args): 54 | with tf.variable_scope('unit_%d' % (i + 1), values=[net]): 55 | unit_depth, unit_depth_bottleneck, unit_stride = unit 56 | net = block.unit_fn(net, depth=unit_depth, depth_bottleneck=unit_depth_bottleneck, 57 | stride=unit_stride) 58 | net = slim.utils.collect_named_outputs(outputs_collections, sc.name, net) 59 | 60 | return net 61 | 62 | 63 | # ResNet arg_scope,arg_scope 64 | def resnet_arg_scope(is_training=True, 65 | weight_decay=0.0001, 66 | batch_norm_decay=0.997, 67 | batch_norm_epsilon=1e-5, 68 | batch_norm_scale=True): 69 | 70 | batch_norm_params = {# batch normalization 71 | 'is_training': is_training, 72 | 'decay': batch_norm_decay, 73 | 'epsilon': batch_norm_epsilon, 74 | 'scale': batch_norm_scale, 75 | 'updates_collections': tf.GraphKeys.UPDATE_OPS, 76 | } 77 | 78 | with slim.arg_scope( # slim.arg_scope [slim.conv2d] 79 | [slim.conv2d], 80 | weights_regularizer=slim.l2_regularizer(weight_decay), # L2 81 | weights_initializer=slim.variance_scaling_initializer(), # 82 | activation_fn=tf.nn.relu, # 83 | normalizer_fn=slim.batch_norm, # BN 84 | normalizer_params=batch_norm_params): 85 | with slim.arg_scope([slim.batch_norm], **batch_norm_params): 86 | with slim.arg_scope([slim.max_pool2d], padding='SAME') as arg_sc: 87 | return arg_sc # arg_scope 88 | 89 | 90 | 91 | #------------------bottleneck-------------------- 92 | @slim.add_arg_scope 93 | def bottleneck(inputs, depth, depth_bottleneck, stride, 94 | outputs_collections=None, scope=None): 95 | """ 96 | Args: 97 | inputs: A tensor of size [batch, height, width, channels]. 98 | depth、depth_bottleneck:、stride三个blocks args 99 | rate: An integer, rate for atrous convolution. 100 | outputs_collections: end_points collection 101 | """ 102 | with tf.variable_scope(scope, 'bottleneck_v2', [inputs]) as sc: 103 | depth_in = slim.utils.last_dimension(inputs.get_shape(), min_rank=4) #最后一个维度,即输出通道数 104 | preact = slim.batch_norm(inputs, activation_fn=tf.nn.relu, scope='preact') 105 | 106 | if depth == depth_in: 107 | # inputs 108 | shortcut = subsample(inputs, stride, 'shortcut') 109 | else: 110 | # 111 | shortcut = slim.conv2d(preact, depth, [1, 1], stride=stride, 112 | normalizer_fn=None, activation_fn=None, 113 | scope='shortcut') 114 | 115 | # 1x1,depth_bottleneck 116 | residual = slim.conv2d(preact, depth_bottleneck, [1, 1], stride=1, scope='conv1') 117 | # 3x3,depth_bottleneck 118 | residual = conv2d_same(residual, depth_bottleneck, 3, stride, scope='conv2') 119 | # 1x1,1,depth, residual 120 | residual = slim.conv2d(residual, depth, [1, 1], stride=1, 121 | normalizer_fn=None, activation_fn=None, 122 | scope='conv3') 123 | 124 | # residual 125 | output = shortcut + residual 126 | 127 | return slim.utils.collect_named_outputs(outputs_collections, sc.name, output) 128 | 129 | 130 | #-------------------resnet_v2------------------ 131 | 132 | def resnet_v2(inputs, blocks, num_classes=None, global_pool=True, 133 | include_root_block=True, reuse=None, scope=None): 134 | 135 | with tf.variable_scope(scope, 'resnet_v2', [inputs], reuse=reuse) as sc: 136 | end_points_collection = sc.original_name_scope + '_end_points' 137 | with slim.arg_scope([slim.conv2d, bottleneck, stack_blocks_dense], 138 | outputs_collections=end_points_collection): 139 | 140 | net = inputs 141 | if include_root_block: # resnet 64 2 7x7 142 | with slim.arg_scope([slim.conv2d], activation_fn=None, normalizer_fn=None): 143 | net = conv2d_same(net, 64, 7, stride=2, scope='conv1') 144 | net = slim.max_pool2d(net, [3, 3], stride=2, scope='pool1') 145 | # 1/4 146 | 147 | net = stack_blocks_dense(net, blocks) 148 | net = slim.batch_norm(net, activation_fn=tf.nn.relu, scope='postnorm') 149 | 150 | if global_pool: 151 | net = tf.reduce_mean(net, [1, 2], name='pool5', keep_dims=True) # tf.reduce_mean, avg_pool 152 | 153 | if num_classes is not None: # 154 | net = slim.conv2d(net, num_classes, [1, 1], activation_fn=None, # 155 | normalizer_fn=None, scope='logits') # num_classes, 1x1 156 | end_points = slim.utils.convert_collection_to_dict(end_points_collection) # collection, python, dict 157 | 158 | if num_classes is not None: 159 | end_points['predictions'] = slim.softmax(net, scope='predictions') # 160 | return net, end_points 161 | 162 | 163 | #------------------- ResNet-50/101/152/200 model-------------------- 164 | 165 | def resnet_v2_50(inputs, num_classes=None, global_pool=True, reuse=None, 166 | scope='resnet_v2_50'): 167 | blocks = [ 168 | Block('block1', bottleneck, [(256, 64, 1)] * 2 + [(256, 64, 2)]), 169 | 170 | # Args:: 171 | # 'block1':Block(scope) 172 | # bottleneck:ResNet V2 173 | # [(256, 64, 1)] * 2 + [(256, 64, 2)]:Block Args,Args, bottleneck 174 | # (256, 64, 1),(256, 64, 2) 175 | # tuple,(depth,depth_bottleneck,stride)。 176 | # (256, 64, 3) bottleneck 177 | # depth 256,depth_bottleneck 64,3: 178 | # [(1*1/s1,64),(3*3/s2,64),(1*1/s1,256)] 179 | 180 | Block('block2', bottleneck, [(512, 128, 1)] * 3 + [(512, 128, 2)]), 181 | Block('block3', bottleneck, [(1024, 256, 1)] * 5 + [(1024, 256, 2)]), 182 | Block('block4', bottleneck, [(2048, 512, 1)] * 3)] 183 | return resnet_v2(inputs, blocks, num_classes, global_pool, 184 | include_root_block=True, reuse=reuse, scope=scope) 185 | 186 | 187 | def resnet_v2_101(inputs, num_classes=None, global_pool=True, reuse=None, 188 | scope='resnet_v2_101'): 189 | """ResNet-101 model of [1]. See resnet_v2() for arg and return description.""" 190 | 191 | blocks = [ 192 | Block('block1', bottleneck, [(256, 64, 1)] * 2 + [(256, 64, 2)]), 193 | Block('block2', bottleneck, [(512, 128, 1)] * 3 + [(512, 128, 2)]), 194 | Block('block3', bottleneck, [(1024, 256, 1)] * 22 + [(1024, 256, 2)]), 195 | Block('block4', bottleneck, [(2048, 512, 1)] * 3)] 196 | return resnet_v2(inputs, blocks, num_classes, global_pool, 197 | include_root_block=True, reuse=reuse, scope=scope) 198 | 199 | 200 | # unit block3 201 | def resnet_v2_152(inputs, num_classes=None, global_pool=True, reuse=None, 202 | scope='resnet_v2_152'): 203 | """ResNet-152 model of [1]. See resnet_v2() for arg and return description.""" 204 | 205 | blocks = [ 206 | Block('block1', bottleneck, [(256, 64, 1)] * 2 + [(256, 64, 2)]), 207 | Block('block2', bottleneck, [(512, 128, 1)] * 7 + [(512, 128, 2)]), 208 | Block('block3', bottleneck, [(1024, 256, 1)] * 35 + [(1024, 256, 2)]), 209 | Block('block4', bottleneck, [(2048, 512, 1)] * 3)] 210 | return resnet_v2(inputs, blocks, num_classes, global_pool, 211 | include_root_block=True, reuse=reuse, scope=scope) 212 | 213 | 214 | # unit block2 215 | def resnet_v2_200(inputs, num_classes=None, global_pool=True, reuse=None, 216 | scope='resnet_v2_200'): 217 | """ResNet-200 model of [2]. See resnet_v2() for arg and return description.""" 218 | 219 | blocks = [ 220 | Block('block1', bottleneck, [(256, 64, 1)] * 2 + [(256, 64, 2)]), 221 | Block('block2', bottleneck, [(512, 128, 1)] * 23 + [(512, 128, 2)]), 222 | Block('block3', bottleneck, [(1024, 256, 1)] * 35 + [(1024, 256, 2)]), 223 | Block('block4', bottleneck, [(2048, 512, 1)] * 3)] 224 | return resnet_v2(inputs, blocks, num_classes, global_pool, 225 | include_root_block=True, reuse=reuse, scope=scope) 226 | 227 | 228 | def AlexNet(inputs, num_classes=10): 229 | 230 | network = tf.layers.conv2d(inputs, 96, 11, strides=4, activation='relu') 231 | network = tf.layers.max_pooling2d(network, 3, strides=2) 232 | network = tf.nn.lrn(network) 233 | network = tf.layers.conv2d(network, 256, 5, activation='relu') 234 | network = tf.layers.max_pooling2d(network, 3, strides=2) 235 | network = tf.nn.lrn(network) 236 | network = tf.layers.conv2d(network, 384, 3, activation='relu') 237 | network = tf.layers.conv2d(network, 384, 3, activation='relu') 238 | network = tf.layers.conv2d(network, 256, 3, activation='relu') 239 | network = tf.layers.max_pooling2d(network, 3, strides=2) 240 | network = tf.nn.lrn(network) 241 | network = tf.layers.flatten(network) 242 | network = tf.layers.dense(network, 4096, activation='tanh') 243 | network = tf.layers.dropout(network, 0.5) 244 | network = tf.layers.dense(network, 4096, activation='tanh') 245 | network = tf.layers.dropout(network, 0.5) 246 | logits = tf.layers.dense(network, num_classes) 247 | 248 | return logits 249 | 250 | def LeNet_5(inputs, num_classes): 251 | 252 | # Hyperparameters 253 | mu = 0 254 | sigma = 0.1 255 | layer_depth = { 256 | 'layer_1' : 6, 257 | 'layer_2' : 16, 258 | 'layer_3' : 120, 259 | 'layer_f1' : 84 260 | } 261 | 262 | 263 | # TODO: Layer 1: Convolutional. Input = 32x32x1. Output = 28x28x6. 264 | conv1_w = tf.Variable(tf.truncated_normal(shape = [5,5,1,6],mean = mu, stddev = sigma)) 265 | conv1_b = tf.Variable(tf.zeros(6)) 266 | conv1 = tf.nn.conv2d(inputs,conv1_w, strides = [1,1,1,1], padding = 'VALID') + conv1_b 267 | # TODO: Activation. 268 | conv1 = tf.nn.relu(conv1) 269 | 270 | # TODO: Pooling. Input = 28x28x6. Output = 14x14x6. 271 | pool_1 = tf.nn.max_pool(conv1,ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'VALID') 272 | 273 | # TODO: Layer 2: Convolutional. Output = 10x10x16. 274 | conv2_w = tf.Variable(tf.truncated_normal(shape = [5,5,6,16], mean = mu, stddev = sigma)) 275 | conv2_b = tf.Variable(tf.zeros(16)) 276 | conv2 = tf.nn.conv2d(pool_1, conv2_w, strides = [1,1,1,1], padding = 'VALID') + conv2_b 277 | # TODO: Activation. 278 | conv2 = tf.nn.relu(conv2) 279 | 280 | # TODO: Pooling. Input = 10x10x16. Output = 5x5x16. 281 | pool_2 = tf.nn.max_pool(conv2, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'VALID') 282 | 283 | # TODO: Flatten. Input = 5x5x16. Output = 400. 284 | fc1 = flatten(pool_2) 285 | 286 | # TODO: Layer 3: Fully Connected. Input = 400. Output = 120. 287 | fc1_w = tf.Variable(tf.truncated_normal(shape = (400,120), mean = mu, stddev = sigma)) 288 | fc1_b = tf.Variable(tf.zeros(120)) 289 | fc1 = tf.matmul(fc1,fc1_w) + fc1_b 290 | 291 | # TODO: Activation. 292 | fc1 = tf.nn.relu(fc1) 293 | 294 | # TODO: Layer 4: Fully Connected. Input = 120. Output = 84. 295 | fc2_w = tf.Variable(tf.truncated_normal(shape = (120,84), mean = mu, stddev = sigma)) 296 | fc2_b = tf.Variable(tf.zeros(84)) 297 | fc2 = tf.matmul(fc1,fc2_w) + fc2_b 298 | # TODO: Activation. 299 | fc2 = tf.nn.relu(fc2) 300 | 301 | # TODO: Layer 5: Fully Connected. Input = 84. Output = 10. 302 | fc3_w = tf.Variable(tf.truncated_normal(shape = (84,num_classes), mean = mu , stddev = sigma)) 303 | fc3_b = tf.Variable(tf.zeros(num_classes)) 304 | logits = tf.matmul(fc2, fc3_w) + fc3_b 305 | 306 | return logits 307 | 308 | def LeNet_5_33(inputs, num_classes): 309 | 310 | # Hyperparameters 311 | mu = 0 312 | sigma = 0.1 313 | layer_depth = { 314 | 'layer_1' : 6, 315 | 'layer_2' : 16, 316 | 'layer_3' : 120, 317 | 'layer_f1' : 84 318 | } 319 | 320 | 321 | # TODO: Layer 1: Convolutional. Input = 33x33x1. Output = 28x28x6. 322 | conv1_w = tf.Variable(tf.truncated_normal(shape = [6,6,1,6],mean = mu, stddev = sigma)) 323 | conv1_b = tf.Variable(tf.zeros(6)) 324 | conv1 = tf.nn.conv2d(inputs,conv1_w, strides = [1,1,1,1], padding = 'VALID') + conv1_b 325 | # TODO: Activation. 326 | conv1 = tf.nn.relu(conv1) 327 | 328 | # TODO: Pooling. Input = 28x28x6. Output = 14x14x6. 329 | pool_1 = tf.nn.max_pool(conv1,ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'VALID') 330 | 331 | # TODO: Layer 2: Convolutional. Output = 10x10x16. 332 | conv2_w = tf.Variable(tf.truncated_normal(shape = [5,5,6,16], mean = mu, stddev = sigma)) 333 | conv2_b = tf.Variable(tf.zeros(16)) 334 | conv2 = tf.nn.conv2d(pool_1, conv2_w, strides = [1,1,1,1], padding = 'VALID') + conv2_b 335 | # TODO: Activation. 336 | conv2 = tf.nn.relu(conv2) 337 | 338 | # TODO: Pooling. Input = 10x10x16. Output = 5x5x16. 339 | pool_2 = tf.nn.max_pool(conv2, ksize = [1,2,2,1], strides = [1,2,2,1], padding = 'VALID') 340 | 341 | # TODO: Flatten. Input = 5x5x16. Output = 400. 342 | fc1 = flatten(pool_2) 343 | 344 | # TODO: Layer 3: Fully Connected. Input = 400. Output = 120. 345 | fc1_w = tf.Variable(tf.truncated_normal(shape = (400,120), mean = mu, stddev = sigma)) 346 | fc1_b = tf.Variable(tf.zeros(120)) 347 | fc1 = tf.matmul(fc1,fc1_w) + fc1_b 348 | 349 | # TODO: Activation. 350 | fc1 = tf.nn.relu(fc1) 351 | 352 | # TODO: Layer 4: Fully Connected. Input = 120. Output = 84. 353 | fc2_w = tf.Variable(tf.truncated_normal(shape = (120,84), mean = mu, stddev = sigma)) 354 | fc2_b = tf.Variable(tf.zeros(84)) 355 | fc2 = tf.matmul(fc1,fc2_w) + fc2_b 356 | # TODO: Activation. 357 | fc2 = tf.nn.relu(fc2) 358 | 359 | # TODO: Layer 5: Fully Connected. Input = 84. Output = 10. 360 | fc3_w = tf.Variable(tf.truncated_normal(shape = (84,num_classes), mean = mu , stddev = sigma)) 361 | fc3_b = tf.Variable(tf.zeros(num_classes)) 362 | logits = tf.matmul(fc2, fc3_w) + fc3_b 363 | 364 | return logits --------------------------------------------------------------------------------