├── Paper └── An in-field automatic wheat disease diagnosis system.pdf ├── Codes ├── PoolLayer.py ├── Dropout.py ├── LRN.py ├── HiddenLayer.py ├── ConvLayer.py ├── SoftmaxLayer.py ├── VGG_S_CNN.py ├── VGG_S_FCN.py ├── VGG16_CNN.py ├── AggregationLayer.py ├── VGG16_FCN.py ├── VGG_S_CNN_Train.py ├── VGG16_CNN_Train.py ├── VGG16_FCN_Train.py ├── VGG_S_FCN_Train.py ├── VGG_S_FCN_Detection.py └── VGG16_FCN_Detection.py └── README.md /Paper/An in-field automatic wheat disease diagnosis system.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LuJiangTHU/DMIL-WDDS/HEAD/Paper/An in-field automatic wheat disease diagnosis system.pdf -------------------------------------------------------------------------------- /Codes/PoolLayer.py: -------------------------------------------------------------------------------- 1 | from theano.tensor.signal.pool import pool_2d 2 | 3 | __author__='lujiang' 4 | 5 | class PoolLayer(object): 6 | 7 | def __init__(self, input, poolsize = (2,2), layer_index=0): 8 | 9 | self.layername = 'Pool' + str(layer_index) 10 | 11 | self.input = input 12 | 13 | self.output = pool_2d( 14 | input = input, 15 | ds = poolsize, 16 | ignore_border = False, 17 | mode='max' 18 | ) -------------------------------------------------------------------------------- /Codes/Dropout.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | import theano 4 | from theano.sandbox.rng_mrg import MRG_RandomStreams as RandomStreams 5 | 6 | class Dropout(object): 7 | # dropput layer 8 | def __init__(self, input, p=0, layer_index=0): 9 | # input is a tensor 10 | self.layername = 'Dropout' + str(layer_index) 11 | self.input = input 12 | self.p = p 13 | self.retain_prob = 1 - self.p 14 | self.srng = RandomStreams() 15 | self.mask = self.srng.binomial(self.input.shape, p=self.retain_prob, dtype=theano.config.floatX) 16 | 17 | if self.p > 0: 18 | self.output = (self.input * self.mask) / self.retain_prob 19 | else: 20 | self.output = self.input 21 | 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DMIL-WDDS 2 | Thanks for your concerns about our work -- "An in-field automatic wheat disease diagnosis system". We have released our source codes in this GitHub repository. 3 | 4 | We are sorry about that the collected dataset "WDD2017" is not publicly available for the time being because of the commercial technology project. 5 | 6 | Note that the pre-trained model “vgg16.pkl” and "vgg_cnn_s.pkl" can be obtained from http://www.vlfeat.org/matconvnet/pretrained/#imagenet-ilsvrc-classification 7 | 8 | Our codes are written in Python and the deep models are implemented with Theano. The relevant path names in our codes should be modified if you want to run these codes. 9 | 10 | If you refer to our work, please note the following reference in your work: "Lu J, Hu J, Zhao G, et al. An in-field automatic wheat disease diagnosis system[J]. Computers and Electronics in Agriculture, 2017, 142: 369-379." 11 | 12 | 13 | -------------------------------------------------------------------------------- /Codes/LRN.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | import theano.tensor as T 4 | 5 | class LRN(object): 6 | 7 | def __init__(self, input, alpha=1e-4, k=2, beta=0.75, n=5, layer_index=0): 8 | 9 | # input is a 4d tensor:(batchsize,channels,raws,cols) 10 | self.layername = 'LRN' + str(layer_index) 11 | self.alpha = alpha 12 | self.k = k 13 | self.beta = beta 14 | self.n = n 15 | self.input = input 16 | if n % 2 == 0: 17 | raise NotImplementedError("only works with odd") 18 | 19 | half_n = self.n // 2 20 | input_sqr = T.sqr(input) 21 | b,ch,r,c = T.shape(input) 22 | extra_channels = T.alloc(0, b,ch+2*half_n,r,c) 23 | input_sqr = T.set_subtensor(extra_channels[:,half_n:half_n+ch,:,:],input_sqr) 24 | 25 | scale = self.k 26 | for i in range(self.n): 27 | scale += self.alpha * input_sqr[:,i:i+ch,:,:] 28 | scale = scale ** self.beta 29 | 30 | self.output = self.input / scale 31 | 32 | -------------------------------------------------------------------------------- /Codes/HiddenLayer.py: -------------------------------------------------------------------------------- 1 | __author__='lujiang' 2 | import numpy 3 | import theano 4 | import theano.tensor as T 5 | from theano.tensor.nnet import relu 6 | 7 | 8 | class HiddenLayer(object): 9 | def __init__(self, rng, input, n_in, n_out, W=None, b=None, layer_index=0): 10 | 11 | self.layername = 'Full' + str(layer_index) 12 | self.input = input 13 | 14 | if W is None: 15 | W_bound = numpy.sqrt(6./(n_in+n_out)) 16 | self.W = theano.shared( 17 | numpy.asarray( 18 | rng.uniform(low= -W_bound, high= W_bound, size=(n_in, n_out)), 19 | dtype= theano.config.floatX 20 | ), 21 | borrow =True 22 | ) 23 | else: 24 | self.W = theano.shared( 25 | value = W.astype(theano.config.floatX), 26 | borrow = True ) 27 | self.W.name = self.layername + '#W' 28 | 29 | 30 | if b is None: 31 | self.b = theano.shared( 32 | numpy.zeros((n_out,),dtype= theano.config.floatX), 33 | borrow =True 34 | ) 35 | else: 36 | self.b = theano.shared( 37 | value = b.astype(theano.config.floatX), 38 | borrow = True 39 | ) 40 | self.b.name = self.layername + '#b' 41 | 42 | 43 | self.output = relu(T.dot(input, self.W) + self.b) 44 | 45 | # parameters of the model 46 | self.params = [self.W, self.b] -------------------------------------------------------------------------------- /Codes/ConvLayer.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import theano 3 | from theano.tensor.nnet import conv2d,relu 4 | 5 | __author__='lujiang' 6 | 7 | class ConvLayer(object): 8 | 9 | def __init__(self, rng, input, filter_shape, W = None, b = None, stride=(1,1), layer_index=0): 10 | 11 | self.layername = 'Conv' + str(layer_index) 12 | self.input = input 13 | # num input feature maps * filter height * filter width 14 | fan_in = numpy.prod(filter_shape[1:]) 15 | 16 | # num output feature maps * filter height * filter width 17 | fan_out = (filter_shape[0]*numpy.prod(filter_shape[2:])) 18 | 19 | # W 20 | if W is None: 21 | W_bound = numpy.sqrt(6./(fan_in+fan_out)) 22 | self.W = theano.shared( 23 | numpy.asarray( 24 | rng.uniform(low= -W_bound, high= W_bound, size=filter_shape), 25 | dtype= theano.config.floatX 26 | ), 27 | borrow =True 28 | ) 29 | else: 30 | self.W = theano.shared( 31 | value = W.astype(theano.config.floatX), 32 | borrow = True 33 | ) 34 | self.W.name = self.layername + '#W' 35 | 36 | # b 37 | if b is None: 38 | self.b = theano.shared( 39 | numpy.zeros((filter_shape[0],),dtype= theano.config.floatX), 40 | borrow =True 41 | ) 42 | else: 43 | self.b = theano.shared( 44 | value = b.astype(theano.config.floatX), 45 | borrow = True 46 | ) 47 | self.b.name = self.layername + '#b' 48 | 49 | # batch size * num feature maps * feature map height * width 50 | conv_out = conv2d( 51 | input= input, 52 | filters = self.W, 53 | filter_shape = filter_shape, 54 | border_mode='half', 55 | subsample=stride 56 | ) 57 | 58 | self.output = relu(conv_out + self.b.dimshuffle('x',0,'x','x')) 59 | 60 | # prepared for the last 3 FC layers 61 | valid_conv_out = conv2d( 62 | input = input, 63 | filters = self.W, 64 | filter_shape = filter_shape, 65 | subsample=stride 66 | ) 67 | self.nopad_output = relu(valid_conv_out + self.b.dimshuffle('x',0,'x','x')) 68 | 69 | # store parameters of this layer 70 | self.params = [self.W, self.b] -------------------------------------------------------------------------------- /Codes/SoftmaxLayer.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import theano 3 | import theano.tensor as T 4 | from theano.tensor.nnet import relu 5 | from theano.tensor.nnet.nnet import softmax 6 | import lasagne 7 | 8 | __author__='lujiang' 9 | 10 | class SoftmaxLayer(object): 11 | 12 | def __init__(self, rng, input, n_in, n_out, W = None, b = None, layer_index=0): 13 | 14 | self.layername = 'Softmax' + str(layer_index) 15 | self.input = input 16 | 17 | # W 18 | if W is None: 19 | W_bound = numpy.sqrt(6./(n_in+n_out)) 20 | self.W = theano.shared( 21 | numpy.asarray( 22 | rng.uniform(low= -W_bound, high= W_bound, size=(n_in, n_out)), 23 | dtype= theano.config.floatX 24 | ), 25 | borrow =True 26 | ) 27 | else: 28 | self.W = theano.shared( 29 | value = W.astype(theano.config.floatX), 30 | borrow = True 31 | ) 32 | self.W.name = self.layername + '#W' 33 | 34 | # b 35 | if b is None: 36 | self.b = theano.shared( 37 | numpy.zeros((n_out,),dtype= theano.config.floatX), 38 | borrow =True 39 | ) 40 | else: 41 | self.b = theano.shared( 42 | value = b.astype(theano.config.floatX), 43 | borrow = True 44 | ) 45 | self.b.name = self.layername + '#b' 46 | 47 | output = relu(T.dot(input, self.W) + self.b) 48 | 49 | self.softmax_output = softmax(output) 50 | 51 | self.pred = self.softmax_output.argmax(axis=1) 52 | 53 | # store parameters of this layer 54 | self.params = [self.W, self.b] 55 | 56 | 57 | 58 | # y:1-7 59 | def cross_entropy(self, y): 60 | return T.mean(lasagne.objectives.categorical_crossentropy(self.softmax_output,y)) 61 | 62 | def squared_error(self, y): 63 | return T.mean(0.5*T.sum((self.softmax_output-y)*(self.softmax_output-y),axis=1)) 64 | 65 | 66 | # error 67 | def errors(self,y): 68 | # (batchsize,) 69 | y_label = T.argmax(y,axis=1) 70 | # check if y_label has same dimension of pred 71 | if y_label.ndim != self.pred.ndim: 72 | raise TypeError( 73 | 'y should have the same shape as self.pred', 74 | ('y',y_label.type,'pred',self.pred.type) 75 | ) 76 | 77 | # check if y is of the correct data type 78 | if y_label.dtype.startswith('int'): 79 | return T.mean(T.neq(self.pred,y_label)) 80 | else: 81 | raise NotImplementedError() 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /Codes/VGG_S_CNN.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | from ConvLayer import ConvLayer 4 | from LRN import LRN 5 | from PoolLayer import PoolLayer 6 | from HiddenLayer import HiddenLayer 7 | from SoftmaxLayer import SoftmaxLayer 8 | import theano 9 | import theano.tensor as T 10 | import lasagne 11 | 12 | class VGG_S_CNN(object): 13 | 14 | def __init__(self,rng,weight,use_last_layer_weight=False): 15 | # weight: list type,0-31,the first 32 W and b 16 | x = T.tensor4('x') 17 | y = T.imatrix('y') 18 | learning_rate = T.scalar('learning_rate') 19 | self.layer1_input = x #224 20 | 21 | self.layer1 = ConvLayer(rng,input=self.layer1_input, filter_shape=(96,3,7,7), layer_index=1, 22 | stride=(2,2),W=weight[0], b=weight[1]) #output: 23 | self.LRN_1 = LRN(input = self.layer1.nopad_output, layer_index=1) 24 | 25 | self.pool1 = PoolLayer(input = self.LRN_1.output, poolsize=(3,3), layer_index=1) # 138 26 | 27 | self.layer2 = ConvLayer(rng,input=self.pool1.output,filter_shape=(256,96,5,5),layer_index=2, 28 | W=weight[2], b=weight[3]) #output: 29 | self.pool2 = PoolLayer(input = self.layer2.nopad_output, poolsize=(2,2), layer_index=2) #67 30 | 31 | self.layer3 = ConvLayer(rng,input=self.pool2.output, filter_shape=(512,256,3,3),layer_index=3, 32 | W=weight[4], b=weight[5]) # 33 | self.layer4 = ConvLayer(rng,input=self.layer3.output, filter_shape=(512,512,3,3),layer_index=4, 34 | W=weight[6], b=weight[7]) # 35 | self.layer5 = ConvLayer(rng,input=self.layer4.output, filter_shape=(512,512,3,3),layer_index=5, 36 | W=weight[8], b=weight[9]) # 37 | self.pool3 = PoolLayer(input = self.layer5.output, poolsize=(3,3), layer_index=3) #23 38 | 39 | 40 | if use_last_layer_weight: #use weight of layer14/15/16 41 | self.layer6 = HiddenLayer(rng,input=self.pool3.output.flatten(ndim=2),n_in=18432,n_out=1024,layer_index=6, 42 | W=weight[10],b=weight[11]) 43 | self.layer7 = HiddenLayer(rng,input=self.layer6.output,n_in=1024,n_out=1024,layer_index=7, 44 | W=weight[12],b=weight[13]) 45 | self.layer8 = SoftmaxLayer(rng,input=self.layer7.output,n_in=1024,n_out=7,layer_index=8, 46 | W=weight[14],b=weight[15]) 47 | else: 48 | self.layer6 = HiddenLayer(rng,input=self.pool3.output.flatten(ndim=2),n_in=18432,n_out=1024,layer_index=6) 49 | self.layer7 = HiddenLayer(rng,input=self.layer6.output,n_in=1024,n_out=1024,layer_index=7) 50 | self.layer8 = SoftmaxLayer(rng,input=self.layer7.output,n_in=1024,n_out=7,layer_index=8) 51 | 52 | # the objective loss 53 | self.loss = self.layer8.squared_error(y) 54 | 55 | self.params = self.layer8.params +self.layer7.params+self.layer6.params +self.layer5.params\ 56 | +self.layer4.params +self.layer3.params +self.layer2.params +self.layer1.params 57 | 58 | # optimization methods 59 | updates = lasagne.updates.nesterov_momentum(self.loss,self.params, 60 | learning_rate=learning_rate, 61 | momentum=0.9) 62 | #updates=lasagne.updates.rmsprop(self.loss, self.params, learning_rate, rho=0.9, epsilon=1e-06) 63 | 64 | 65 | self.train = theano.function(inputs = [x,y,learning_rate], 66 | outputs= [self.loss,self.layer8.errors(y)], 67 | updates= updates, 68 | allow_input_downcast=True) 69 | 70 | self.test = theano.function(inputs = [x,y], 71 | outputs= [self.loss,self.layer8.errors(y)], 72 | allow_input_downcast=True) 73 | 74 | #self.detection = theano.function( 75 | # inputs = [x,y], 76 | # outputs= [self.layer16.pred,self.layer16.errors(y),self.layer16.pro_instance,self.layer16.pro_bag], 77 | # allow_input_downcast=True ) 78 | 79 | -------------------------------------------------------------------------------- /Codes/VGG_S_FCN.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | from ConvLayer import ConvLayer 4 | from LRN import LRN 5 | from PoolLayer import PoolLayer 6 | from AggregationLayer import AggregationLayer 7 | import theano 8 | import theano.tensor as T 9 | import lasagne 10 | 11 | class VGG_S_FCN(object): 12 | 13 | def __init__(self,rng,weight,agg_func='soft',use_last_layer_weight=False): 14 | # weight: list type,0-15,the first 16 W and b 15 | x = T.tensor4('x') 16 | y = T.imatrix('y') 17 | learning_rate = T.scalar('learning_rate') 18 | self.layer1_input = x #832 19 | 20 | self.layer1 = ConvLayer(rng,input=self.layer1_input, filter_shape=(96,3,7,7), layer_index=1, 21 | stride=(2,2),W=weight[0], b=weight[1]) #output:413 22 | self.LRN_1 = LRN(input = self.layer1.nopad_output, layer_index=1) 23 | 24 | self.pool1 = PoolLayer(input = self.LRN_1.output, poolsize=(3,3), layer_index=1) # 138 25 | 26 | self.layer2 = ConvLayer(rng,input=self.pool1.output,filter_shape=(256,96,5,5),layer_index=2, 27 | W=weight[2], b=weight[3]) #output: 134 28 | self.pool2 = PoolLayer(input = self.layer2.nopad_output, poolsize=(2,2), layer_index=2) #67 29 | 30 | self.layer3 = ConvLayer(rng,input=self.pool2.output, filter_shape=(512,256,3,3),layer_index=3, 31 | W=weight[4], b=weight[5]) #67 32 | self.layer4 = ConvLayer(rng,input=self.layer3.output, filter_shape=(512,512,3,3),layer_index=4, 33 | W=weight[6], b=weight[7]) #67 34 | self.layer5 = ConvLayer(rng,input=self.layer4.output, filter_shape=(512,512,3,3),layer_index=5, 35 | W=weight[8], b=weight[9]) #67 36 | self.pool3 = PoolLayer(input = self.layer5.output, poolsize=(3,3), layer_index=3) #23 37 | 38 | ## change FC1/FC2/FC3 layers to Convlayers14/15/16 39 | 40 | if use_last_layer_weight: #use weight of layer14/15/16 41 | self.layer6 = ConvLayer(rng,input=self.pool3.output,filter_shape=(1024,512,6,6),layer_index=6, 42 | W=weight[10],b=weight[11]) #18 43 | self.layer7 = ConvLayer(rng,input=self.layer6.nopad_output,filter_shape=(1024,1024,1,1),layer_index=7, 44 | W=weight[12],b=weight[13]) #18 45 | self.layer8 = AggregationLayer(rng,input=self.layer7.nopad_output,filter_shape=(7,1024,1,1),layer_index=8, 46 | W=weight[14],b=weight[15],agg_func=agg_func) #18 47 | else: 48 | self.layer6 = ConvLayer(rng,input=self.pool3.output,filter_shape=(1024,512,6,6),layer_index=6)#18 49 | self.layer7 = ConvLayer(rng,input=self.layer6.nopad_output,filter_shape=(1024,1024,1,1),layer_index=7)#18 50 | self.layer8 = AggregationLayer(rng,input=self.layer7.nopad_output,filter_shape=(7,1024,1,1),layer_index=8, 51 | agg_func=agg_func)#18 52 | 53 | 54 | # the objective loss 55 | self.loss = self.layer8.squared_error(y) 56 | 57 | self.params = self.layer8.params+self.layer7.params+self.layer6.params+self.layer5.params\ 58 | +self.layer4.params+self.layer3.params+self.layer2.params +self.layer1.params 59 | 60 | # optimization methods 61 | updates = lasagne.updates.nesterov_momentum(self.loss,self.params, 62 | learning_rate=learning_rate, 63 | momentum=0.9) 64 | 65 | self.train = theano.function(inputs = [x,y,learning_rate], 66 | outputs= [self.loss,self.layer8.errors(y)], 67 | updates= updates, 68 | allow_input_downcast=True) 69 | 70 | self.test = theano.function(inputs = [x,y], 71 | outputs= [self.loss,self.layer8.errors(y)], 72 | allow_input_downcast=True) 73 | 74 | self.detection = theano.function( 75 | inputs = [x,y], 76 | outputs= [self.layer8.pred,self.layer8.errors(y), 77 | self.layer8.pro_instance,self.layer8.pro_bag], 78 | allow_input_downcast=True ) 79 | 80 | -------------------------------------------------------------------------------- /Codes/VGG16_CNN.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | from ConvLayer import ConvLayer 4 | from PoolLayer import PoolLayer 5 | from HiddenLayer import HiddenLayer 6 | from SoftmaxLayer import SoftmaxLayer 7 | import theano 8 | import theano.tensor as T 9 | import lasagne 10 | 11 | class VGG16_CNN(object): 12 | 13 | def __init__(self,rng,weight,use_last_layer_weight=False): 14 | # weight: list type,0-31,the first 32 W and b 15 | x = T.tensor4('x') 16 | y = T.imatrix('y') 17 | learning_rate = T.scalar('learning_rate') 18 | self.layer1_input = x #224 19 | 20 | self.layer1 = ConvLayer(rng,input=self.layer1_input, filter_shape=(64,3,3,3), layer_index=1, W=weight[0], b=weight[1]) 21 | self.layer2 = ConvLayer(rng,input=self.layer1.output,filter_shape=(64,64,3,3),layer_index=2, W=weight[2], b=weight[3]) 22 | self.pool1 = PoolLayer(input = self.layer2.output, poolsize=(2,2), layer_index=1) #112 23 | 24 | self.layer3 = ConvLayer(rng,input=self.pool1.output, filter_shape=(128,64,3,3),layer_index=3, W=weight[4], b=weight[5]) 25 | self.layer4 = ConvLayer(rng,input=self.layer3.output,filter_shape=(128,128,3,3),layer_index=4,W=weight[6], b=weight[7]) 26 | self.pool2 = PoolLayer(input = self.layer4.output, poolsize=(2,2), layer_index=2) #56 27 | 28 | self.layer5 = ConvLayer(rng,input=self.pool2.output, filter_shape=(256,128,3,3),layer_index=5,W=weight[8], b=weight[9]) 29 | self.layer6 = ConvLayer(rng,input=self.layer5.output,filter_shape=(256,256,3,3),layer_index=6,W=weight[10], b=weight[11]) 30 | self.layer7 = ConvLayer(rng,input=self.layer6.output,filter_shape=(256,256,3,3),layer_index=7,W=weight[12], b=weight[13]) 31 | self.pool3 = PoolLayer(input = self.layer7.output, poolsize=(2,2), layer_index=3) #28 32 | 33 | self.layer8 = ConvLayer(rng,input=self.pool3.output, filter_shape=(512,256,3,3),layer_index=8,W=weight[14], b=weight[15]) 34 | self.layer9 = ConvLayer(rng,input=self.layer8.output,filter_shape=(512,512,3,3),layer_index=9,W=weight[16], b=weight[17]) 35 | self.layer10= ConvLayer(rng,input=self.layer9.output,filter_shape=(512,512,3,3),layer_index=10,W=weight[18],b=weight[19]) 36 | self.pool4 = PoolLayer(input = self.layer10.output, poolsize=(2,2), layer_index=4) #14 37 | 38 | self.layer11 = ConvLayer(rng,input=self.pool4.output,filter_shape=(512,512,3,3),layer_index=11,W=weight[20],b=weight[21]) 39 | self.layer12 = ConvLayer(rng,input=self.layer11.output,filter_shape=(512,512,3,3),layer_index=12,W=weight[22],b=weight[23]) 40 | self.layer13 = ConvLayer(rng,input=self.layer12.output,filter_shape=(512,512,3,3),layer_index=13,W=weight[24],b=weight[25]) 41 | self.pool5 = PoolLayer(input = self.layer13.output, poolsize=(2,2), layer_index=5) #7 42 | 43 | if use_last_layer_weight: #use weight of layer14/15/16 44 | self.layer14 = HiddenLayer(rng,input=self.pool5.output.flatten(ndim=2),n_in=25088,n_out=1024,layer_index=14, 45 | W=weight[26],b=weight[27]) 46 | self.layer15 = HiddenLayer(rng,input=self.layer14.output,n_in=1024,n_out=1024,layer_index=15, 47 | W=weight[28],b=weight[29]) 48 | self.layer16 = SoftmaxLayer(rng,input=self.layer15.output,n_in=1024,n_out=7,layer_index=16, 49 | W=weight[30],b=weight[31]) 50 | else: 51 | self.layer14 = HiddenLayer(rng,input=self.pool5.output.flatten(ndim=2),n_in=25088,n_out=1024,layer_index=14) 52 | self.layer15 = HiddenLayer(rng,input=self.layer14.output,n_in=1024,n_out=1024,layer_index=15) 53 | self.layer16 = SoftmaxLayer(rng,input=self.layer15.output,n_in=1024,n_out=7,layer_index=16) 54 | 55 | 56 | # the objective loss 57 | self.loss = self.layer16.squared_error(y) 58 | 59 | self.params = self.layer16.params+self.layer15.params+self.layer14.params+self.layer13.params+self.layer12.params\ 60 | +self.layer11.params+self.layer10.params+self.layer9.params +self.layer8.params +self.layer7.params\ 61 | +self.layer6.params +self.layer5.params +self.layer4.params +self.layer3.params +self.layer2.params\ 62 | +self.layer1.params 63 | 64 | # optimization methods 65 | updates = lasagne.updates.nesterov_momentum(self.loss,self.params, 66 | learning_rate=learning_rate, 67 | momentum=0.9) 68 | 69 | self.train = theano.function(inputs = [x,y,learning_rate], 70 | outputs= [self.loss,self.layer16.errors(y)], 71 | updates= updates, 72 | allow_input_downcast=True) 73 | 74 | self.test = theano.function(inputs = [x,y], 75 | outputs= [self.loss,self.layer16.errors(y)], 76 | allow_input_downcast=True) 77 | 78 | #self.detection = theano.function( 79 | # inputs = [x,y], 80 | # outputs= [self.layer16.pred,self.layer16.errors(y),self.layer16.pro_instance,self.layer16.pro_bag], 81 | # allow_input_downcast=True ) 82 | 83 | -------------------------------------------------------------------------------- /Codes/AggregationLayer.py: -------------------------------------------------------------------------------- 1 | import numpy 2 | import theano 3 | import theano.tensor as T 4 | from theano.tensor.nnet import conv2d,softmax,sigmoid,relu 5 | 6 | __author__='lujiang' 7 | 8 | class AggregationLayer(object): 9 | 10 | def __init__(self, rng, input, filter_shape, W = None, b = None, agg_func='soft', layer_index=0, alpha = 2.5): 11 | 12 | self.layername = 'Aggregation' + str(layer_index) 13 | self.input = input 14 | 15 | # num input feature maps * filter height * filter width 16 | fan_in = numpy.prod(filter_shape[1:]) 17 | 18 | # num output feature maps * filter height * filter width 19 | fan_out = (filter_shape[0]*numpy.prod(filter_shape[2:])) 20 | 21 | # W 22 | if W is None: 23 | W_bound = numpy.sqrt(6./(fan_in+fan_out)) 24 | self.W = theano.shared( 25 | numpy.asarray( 26 | rng.uniform(low= -W_bound, high= W_bound, size=filter_shape), 27 | dtype= theano.config.floatX 28 | ), 29 | borrow =True 30 | ) 31 | else: 32 | self.W = theano.shared( 33 | value = W.astype(theano.config.floatX), 34 | borrow = True 35 | ) 36 | self.W.name = self.layername + '#W' 37 | 38 | # b 39 | if b is None: 40 | self.b = theano.shared( 41 | numpy.zeros((filter_shape[0],),dtype= theano.config.floatX), 42 | borrow =True 43 | ) 44 | else: 45 | self.b = theano.shared( 46 | value = b.astype(theano.config.floatX), 47 | borrow = True 48 | ) 49 | self.b.name = self.layername + '#b' 50 | 51 | # batch size * num feature maps * feature map height * width 52 | # size : batch size * kinds num * height * width 53 | self.valid_conv_out = conv2d( 54 | input = input, 55 | filters = self.W, 56 | filter_shape = filter_shape, 57 | ) 58 | 59 | 60 | if agg_func == 'soft': 61 | # ------- combining function is softmax ,ML logistic regression (multi-class)-------- 62 | # batchsize * kind num * height * width 63 | self.pro_instance = sigmoid(self.valid_conv_out + self.b.dimshuffle('x',0,'x','x')) 64 | # batchsize * kind num *(height*width) 65 | self.pro_spread = self.pro_instance.flatten(ndim=3) 66 | 67 | # (batchsize,kind num) 68 | self.pro_bag = (T.exp(alpha*self.pro_spread) * self.pro_spread).sum(axis=2) / \ 69 | T.exp(alpha*self.pro_spread).sum(axis=2) 70 | 71 | # (batchsize,) 72 | self.pred = self.pro_bag.argmax(axis=1) 73 | 74 | # multi-image to one plant object 75 | self.ensemblePred = self.pro_bag.mean(axis=0).argmax() 76 | # ------------------------------------------------------------------------- 77 | elif agg_func == 'max': 78 | # ------- combining function is hardmax ,ML logistic regression (multi-class)-------- 79 | # batchsize * kind num * height * width 80 | self.pro_instance = sigmoid(self.valid_conv_out + self.b.dimshuffle('x',0,'x','x')) 81 | # batchsize * kind num *(height*width) 82 | self.pro_spread = self.pro_instance.flatten(ndim=3) 83 | 84 | # (batchsize,kind num) 85 | self.pro_bag = self.pro_spread.max(axis=2) 86 | 87 | # (batchsize,) 88 | self.pred = self.pro_bag.argmax(axis=1) 89 | 90 | # multi-image to one plant object 91 | self.ensemblePred = self.pro_bag.mean(axis=0).argmax() 92 | # ------------------------------------------------------------------------- 93 | else: 94 | 95 | # ------- combining function is mean, ML logistic regression (multi-class)-------- 96 | # batchsize * kind num * height * width 97 | self.pro_instance = sigmoid(self.valid_conv_out + self.b.dimshuffle('x',0,'x','x')) 98 | # batchsize * kind num *(height*width) 99 | self.pro_spread = self.pro_instance.flatten(ndim=3) 100 | 101 | # (batchsize,kind num) 102 | self.pro_bag = self.pro_spread.mean(axis=2) 103 | 104 | # (batchsize,) 105 | self.pred = self.pro_bag.argmax(axis=1) 106 | 107 | # multi-image to one plant object 108 | self.ensemblePred = self.pro_bag.mean(axis=0).argmax() 109 | # ------------------------------------------------------------------------- 110 | 111 | # store parameters of this layer 112 | self.params = [self.W, self.b] 113 | 114 | 115 | def squared_error(self, y): 116 | return T.mean(0.5*T.sum((self.pro_bag-y)*(self.pro_bag-y),axis=1)) 117 | 118 | 119 | # error 120 | def errors(self,y): 121 | # (batchsize,) 122 | y_label = T.argmax(y,axis=1) 123 | # check if y_label has same dimension of pred 124 | if y_label.ndim != self.pred.ndim: 125 | raise TypeError( 126 | 'y should have the same shape as self.pred', 127 | ('y',y_label.type,'pred',self.pred.type) 128 | ) 129 | 130 | # check if y is of the correct data type 131 | if y_label.dtype.startswith('int'): 132 | return T.mean(T.neq(self.pred,y_label)) 133 | else: 134 | raise NotImplementedError() 135 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /Codes/VGG16_FCN.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | from ConvLayer import ConvLayer 4 | from PoolLayer import PoolLayer 5 | from AggregationLayer import AggregationLayer 6 | import theano 7 | import theano.tensor as T 8 | import lasagne 9 | 10 | class VGG16_FCN(object): 11 | 12 | def __init__(self,rng,weight,agg_func='soft',use_last_layer_weight=False): 13 | # weight: list type,0-31,the first 32 W and b 14 | x = T.tensor4('x') 15 | y = T.imatrix('y') 16 | learning_rate = T.scalar('learning_rate') 17 | self.layer1_input = x #832 18 | 19 | self.layer1 = ConvLayer(rng,input=self.layer1_input, filter_shape=(64,3,3,3), layer_index=1, W=weight[0], b=weight[1]) 20 | self.layer2 = ConvLayer(rng,input=self.layer1.output,filter_shape=(64,64,3,3),layer_index=2, W=weight[2], b=weight[3]) 21 | self.pool1 = PoolLayer(input = self.layer2.output, poolsize=(2,2), layer_index=1) #416 22 | 23 | self.layer3 = ConvLayer(rng,input=self.pool1.output, filter_shape=(128,64,3,3),layer_index=3, W=weight[4], b=weight[5]) 24 | self.layer4 = ConvLayer(rng,input=self.layer3.output,filter_shape=(128,128,3,3),layer_index=4,W=weight[6], b=weight[7]) 25 | self.pool2 = PoolLayer(input = self.layer4.output, poolsize=(2,2), layer_index=2) #208 26 | 27 | self.layer5 = ConvLayer(rng,input=self.pool2.output, filter_shape=(256,128,3,3),layer_index=5,W=weight[8], b=weight[9]) 28 | self.layer6 = ConvLayer(rng,input=self.layer5.output,filter_shape=(256,256,3,3),layer_index=6,W=weight[10], b=weight[11]) 29 | self.layer7 = ConvLayer(rng,input=self.layer6.output,filter_shape=(256,256,3,3),layer_index=7,W=weight[12], b=weight[13]) 30 | self.pool3 = PoolLayer(input = self.layer7.output, poolsize=(2,2), layer_index=3) #104 31 | 32 | self.layer8 = ConvLayer(rng,input=self.pool3.output, filter_shape=(512,256,3,3),layer_index=8,W=weight[14], b=weight[15]) 33 | self.layer9 = ConvLayer(rng,input=self.layer8.output,filter_shape=(512,512,3,3),layer_index=9,W=weight[16], b=weight[17]) 34 | self.layer10= ConvLayer(rng,input=self.layer9.output,filter_shape=(512,512,3,3),layer_index=10,W=weight[18],b=weight[19]) 35 | self.pool4 = PoolLayer(input = self.layer10.output, poolsize=(2,2), layer_index=4) #52 36 | 37 | self.layer11 = ConvLayer(rng,input=self.pool4.output,filter_shape=(512,512,3,3),layer_index=11,W=weight[20],b=weight[21]) 38 | self.layer12 = ConvLayer(rng,input=self.layer11.output,filter_shape=(512,512,3,3),layer_index=12,W=weight[22],b=weight[23]) 39 | self.layer13 = ConvLayer(rng,input=self.layer12.output,filter_shape=(512,512,3,3),layer_index=13,W=weight[24],b=weight[25]) 40 | self.pool5 = PoolLayer(input = self.layer13.output, poolsize=(2,2), layer_index=5) #26 41 | 42 | ## change FC1/FC2/FC3 layers to Convlayers14/15/16 43 | 44 | if use_last_layer_weight: #use weight of layer14/15/16 45 | self.layer14 = ConvLayer(rng,input=self.pool5.output,filter_shape=(1024,512,7,7),layer_index=14, 46 | W=weight[26],b=weight[27]) #20 47 | self.layer15 = ConvLayer(rng,input=self.layer14.nopad_output,filter_shape=(1024,1024,1,1),layer_index=15, 48 | W=weight[28],b=weight[29]) #20 49 | self.layer16 = AggregationLayer(rng,input=self.layer15.nopad_output,filter_shape=(7,1024,1,1),layer_index=16, 50 | W=weight[30],b=weight[31],agg_func=agg_func) #20 51 | else: 52 | self.layer14 = ConvLayer(rng,input=self.pool5.output,filter_shape=(1024,512,7,7),layer_index=14) 53 | self.layer15 = ConvLayer(rng,input=self.layer14.nopad_output,filter_shape=(1024,1024,1,1),layer_index=15) 54 | self.layer16 = AggregationLayer(rng,input=self.layer15.nopad_output,filter_shape=(7,1024,1,1),layer_index=16, 55 | agg_func=agg_func) 56 | 57 | 58 | # the objective loss 59 | self.loss = self.layer16.squared_error(y) 60 | 61 | self.params = self.layer16.params+self.layer15.params+self.layer14.params+self.layer13.params+self.layer12.params\ 62 | +self.layer11.params+self.layer10.params+self.layer9.params +self.layer8.params +self.layer7.params\ 63 | +self.layer6.params +self.layer5.params +self.layer4.params +self.layer3.params +self.layer2.params\ 64 | +self.layer1.params 65 | 66 | # optimization methods 67 | updates = lasagne.updates.nesterov_momentum(self.loss,self.params, 68 | learning_rate=learning_rate, 69 | momentum=0.9) 70 | 71 | self.train = theano.function(inputs = [x,y,learning_rate], 72 | outputs= [self.loss,self.layer16.errors(y)], 73 | updates= updates, 74 | allow_input_downcast=True) 75 | 76 | self.test = theano.function(inputs = [x,y], 77 | outputs= [self.loss,self.layer16.errors(y)], 78 | allow_input_downcast=True) 79 | 80 | self.detection = theano.function( 81 | inputs = [x,y], 82 | outputs= [self.layer16.pred,self.layer16.errors(y), 83 | self.layer16.pro_instance,self.layer16.pro_bag], 84 | allow_input_downcast=True ) 85 | 86 | self.feamap = theano.function( 87 | inputs=[x], 88 | outputs=[self.pool1.output, self.pool2.output, self.pool3.output, self.pool4.output,self.pool5.output], 89 | allow_input_downcast=True) 90 | 91 | -------------------------------------------------------------------------------- /Codes/VGG_S_CNN_Train.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | import os 4 | import numpy as np 5 | import h5py 6 | import pickle 7 | from VGG_S_CNN import VGG_S_CNN 8 | from PIL import Image 9 | import random 10 | 11 | ## different random seeds 12 | rng = np.random.RandomState(1234) #cnn16fold1_2 13 | 14 | #rng = np.random.RandomState(23455)#cnn16fold1_2 15 | #rng = np.random.RandomState(11) #cnn16fold1_1 16 | #rng = np.random.RandomState(564) #cnn16fold1_2 17 | #rng = np.random.RandomState(9852)#cnn16fold1_3 18 | 19 | 20 | 21 | ############################## 22 | #Loading pre-training params # 23 | ############################## 24 | print('...loading pre-training params') 25 | f = open('/home/trunk/disk1/lujiang/vgg_cnn_s.pkl') 26 | VGGSmodel = pickle.load(f) 27 | f.close() 28 | W = VGGSmodel['values'][0:10] 29 | meanValue = VGGSmodel['mean image'].mean(axis=1).mean(axis=1) 30 | 31 | 32 | ####################### 33 | ##### Build Model ##### 34 | ####################### 35 | print('...building the model') 36 | VGGS_CNN_model = VGG_S_CNN(rng,weight=W, use_last_layer_weight=False) 37 | 38 | 39 | ####################### 40 | ##### Train Model ##### 41 | ####################### 42 | print('......training') 43 | batchsize = 45 44 | dirs_Trn = [] 45 | # /home/trunk/disk1/lujiang/ 46 | dirs_Trn.extend(os.listdir('WDD/fold1')) 47 | dirs_Trn.extend(os.listdir('WDD/fold2')) 48 | dirs_Trn.extend(os.listdir('WDD/fold3')) 49 | dirs_Trn.extend(os.listdir('WDD/fold4')) 50 | 51 | dirs_Tst = os.listdir('WDD/fold5') 52 | 53 | dirs_Trn = np.array(dirs_Trn) 54 | dirs_Trn_info = np.empty((len(dirs_Trn),2),dtype='|S29') 55 | dirs_Trn_info[:,0] = dirs_Trn 56 | dirs_Trn_info[0:len(dirs_Tst),1]= 'fold1' 57 | dirs_Trn_info[len(dirs_Tst):2*len(dirs_Tst),1]= 'fold2' 58 | dirs_Trn_info[2*len(dirs_Tst):3*len(dirs_Tst),1]= 'fold3' 59 | dirs_Trn_info[3*len(dirs_Tst):4*len(dirs_Tst),1]= 'fold4' 60 | dirs_Trn = dirs_Trn_info.tolist() # image name + fold name 61 | 62 | f1 = open('WDD/fold1_label.txt') 63 | f2 = open('WDD/fold2_label.txt') 64 | f3 = open('WDD/fold3_label.txt') 65 | f4 = open('WDD/fold4_label.txt') 66 | list1 = np.asarray([x.split() for x in f1.readlines()]) 67 | list2 = np.asarray([x.split() for x in f2.readlines()]) 68 | list3 = np.asarray([x.split() for x in f3.readlines()]) 69 | list4 = np.asarray([x.split() for x in f4.readlines()]) 70 | Trn_label_list = np.concatenate((list1,list2,list3,list4)) 71 | f1.close() 72 | f2.close() 73 | f3.close() 74 | f4.close() 75 | 76 | f = open('WDD/fold5_label.txt') 77 | Tst_label_list = np.asarray([x.split() for x in f.readlines()]) 78 | f.close() 79 | 80 | fold_batch = len(dirs_Tst) / batchsize #41 81 | 82 | n_epoch = 60 83 | base_lr = 0.0001 84 | 85 | best_tst_error = np.inf 86 | current_tst_loss = np.inf 87 | best_iter = 0 88 | for epoch in range(n_epoch): 89 | 90 | random.shuffle(dirs_Trn) 91 | 92 | # learning rate for different epoch 93 | lr = 10** -(epoch/10) * base_lr 94 | print('*********** learning_rate: %f ************' % lr) 95 | 96 | for k in range(fold_batch*4): #164 97 | iter = fold_batch*4 * epoch + k +1 98 | # load train data 99 | batch_input_x = [] 100 | batch_input_y = [] 101 | 102 | for i in range(batchsize): #45 103 | index = k*batchsize + i 104 | img = Image.open('WDD/'+dirs_Trn[index][1]+'/'+dirs_Trn[index][0]) 105 | img = np.array(img.resize((224,224),Image.ANTIALIAS)).transpose(2,0,1)-meanValue.reshape(-1,1,1) 106 | label = np.zeros(7,dtype='int32') 107 | hot_id = int(Trn_label_list[np.where(Trn_label_list==dirs_Trn[index])[0],1][0]) 108 | label[hot_id-1] = label[hot_id-1]+1 109 | batch_input_x.append(img) 110 | batch_input_y.append(label) 111 | 112 | batch_input_x = np.asarray(batch_input_x) 113 | batch_input_y = np.asarray(batch_input_y,dtype='int32') 114 | loss_iter, error_iter = VGGS_CNN_model.train(batch_input_x,batch_input_y,lr) 115 | print('Epoch:%d, Iter:%d, TrainMinibatch: %i/%i, miniLoss:%f, miniTrainError: %f%%' % 116 | (epoch+1, iter, k+1, fold_batch*4, loss_iter, error_iter*100.)) 117 | 118 | 119 | if iter % 100 ==0: 120 | tst_loss =[] 121 | tst_error = [] 122 | for k in range(fold_batch): #41 123 | # load tst data 124 | batch_input_x = [] 125 | batch_input_y = [] 126 | for i in range(batchsize): #45 127 | index = k*batchsize + i 128 | img = Image.open('WDD/fold5/'+dirs_Tst[index]) 129 | img = np.array(img.resize((224,224),Image.ANTIALIAS)).transpose(2,0,1)-meanValue.reshape(-1,1,1) 130 | label = np.zeros(7,dtype='int32') 131 | hot_id = int(Tst_label_list[np.where(Tst_label_list==(dirs_Tst[index]))[0],1][0]) 132 | label[hot_id-1] = label[hot_id-1]+1 133 | batch_input_x.append(img) 134 | batch_input_y.append(label) 135 | 136 | batch_input_x = np.asarray(batch_input_x) 137 | batch_input_y = np.asarray(batch_input_y,dtype='int32') 138 | 139 | loss_iter, error_iter = VGGS_CNN_model.test(batch_input_x,batch_input_y) 140 | tst_loss.append(loss_iter) 141 | tst_error.append(error_iter) 142 | print('TestSet(Epoch:%d, Iter:%d) minibatch: %i/%i, miniTestError: %f%%' % 143 | (epoch+1, iter, k+1, fold_batch, error_iter*100.)) 144 | 145 | 146 | 147 | tst_loss = np.mean(np.asarray(tst_loss)) 148 | tst_error = np.mean(np.asarray(tst_error)) 149 | 150 | print('-------------------------------------------------------------------------------------') 151 | print('Epoch:%d, Iter:%d-- TestError:%f%%, TestLoss: %f' % 152 | (epoch+1, iter, tst_error*100., tst_loss)) 153 | print('-------------------------------------------------------------------------------------') 154 | 155 | # save the best model 156 | if tst_error < best_tst_error: 157 | best_tst_error = tst_error 158 | best_iter = iter 159 | current_tst_loss = tst_loss 160 | 161 | file = os.listdir('VGGS_CNN_tstfold5_1') 162 | if len(file)!=0: 163 | os.remove('VGGS_CNN_tstfold5_1/'+file[0]) 164 | 165 | model_file = 'VGGS_CNN_tstfold5_1/'+str(epoch+1)+'_'+str(iter)+'.h5' 166 | f = h5py.File(model_file) 167 | for p in VGGS_CNN_model.params: 168 | f[p.name] = p.get_value() 169 | f.close() 170 | 171 | 172 | print('Optimation complete.') 173 | print('Best test score of %f%% obtained at iteration %i, with test loss %f' % 174 | (best_tst_error*100., best_iter,current_tst_loss)) -------------------------------------------------------------------------------- /Codes/VGG16_CNN_Train.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | import os 4 | import numpy as np 5 | import h5py 6 | import pickle 7 | from VGG16_CNN import VGG16_CNN 8 | from PIL import Image 9 | import random 10 | 11 | ## different random seeds 12 | rng = np.random.RandomState(1234) #cnn16fold1_2 13 | 14 | #rng = np.random.RandomState(23455) 15 | #rng = np.random.RandomState(1123) 16 | #rng = np.random.RandomState(564) 17 | #rng = np.random.RandomState(9852) 18 | 19 | 20 | 21 | ############################## 22 | #Loading pre-training params # 23 | ############################## 24 | print('...loading pre-training params') 25 | f = open('/home/trunk/disk1/lujiang/vgg16.pkl') 26 | VGG16model = pickle.load(f) 27 | f.close() 28 | W = VGG16model['param values'][0:26] 29 | meanValue = VGG16model['mean value'] 30 | 31 | 32 | ####################### 33 | ##### Build Model ##### 34 | ####################### 35 | print('...building the model') 36 | VGG16_CNN_model = VGG16_CNN(rng,weight=W, use_last_layer_weight=False) 37 | 38 | 39 | ####################### 40 | ##### Train Model ##### 41 | ####################### 42 | print('......training') 43 | 44 | batchsize = 45 45 | dirs_Trn = [] 46 | 47 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold1')) 48 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold2')) 49 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold3')) 50 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold4')) 51 | 52 | dirs_Tst = os.listdir('/home/trunk/disk1/lujiang/WDD/fold5') 53 | 54 | dirs_Trn = np.array(dirs_Trn) 55 | dirs_Trn_info = np.empty((len(dirs_Trn),2),dtype='|S29') 56 | dirs_Trn_info[:,0] = dirs_Trn 57 | dirs_Trn_info[0:len(dirs_Tst),1]= 'fold1' 58 | dirs_Trn_info[len(dirs_Tst):2*len(dirs_Tst),1]= 'fold2' 59 | dirs_Trn_info[2*len(dirs_Tst):3*len(dirs_Tst),1]= 'fold3' 60 | dirs_Trn_info[3*len(dirs_Tst):4*len(dirs_Tst),1]= 'fold4' 61 | dirs_Trn = dirs_Trn_info.tolist() # image name + fold name 62 | 63 | f1 = open('/home/trunk/disk1/lujiang/WDD/fold1_label.txt') 64 | f2 = open('/home/trunk/disk1/lujiang/WDD/fold2_label.txt') 65 | f3 = open('/home/trunk/disk1/lujiang/WDD/fold3_label.txt') 66 | f4 = open('/home/trunk/disk1/lujiang/WDD/fold4_label.txt') 67 | list1 = np.asarray([x.split() for x in f1.readlines()]) 68 | list2 = np.asarray([x.split() for x in f2.readlines()]) 69 | list3 = np.asarray([x.split() for x in f3.readlines()]) 70 | list4 = np.asarray([x.split() for x in f4.readlines()]) 71 | Trn_label_list = np.concatenate((list1,list2,list3,list4)) 72 | f1.close() 73 | f2.close() 74 | f3.close() 75 | f4.close() 76 | 77 | f = open('/home/trunk/disk1/lujiang/WDD/fold5_label.txt') 78 | Tst_label_list = np.asarray([x.split() for x in f.readlines()]) 79 | f.close() 80 | 81 | fold_batch = len(dirs_Tst) / batchsize #41 82 | 83 | n_epoch = 60 84 | base_lr = 0.001 85 | 86 | best_tst_error = np.inf 87 | current_tst_loss = np.inf 88 | best_iter = 0 89 | 90 | for epoch in range(n_epoch): 91 | 92 | random.shuffle(dirs_Trn) 93 | 94 | # learning rate for different epoch 95 | lr = 10** -(epoch/10) * base_lr 96 | print('*********** learning_rate: %f ************' % lr) 97 | 98 | for k in range(fold_batch*4): #164 99 | iter = fold_batch*4 * epoch + k +1 100 | # load train data 101 | batch_input_x = [] 102 | batch_input_y = [] 103 | 104 | for i in range(batchsize): #45 105 | index = k*batchsize + i 106 | img = Image.open('/home/trunk/disk1/lujiang/WDD/'+dirs_Trn[index][1]+'/'+dirs_Trn[index][0]) 107 | img = np.array(img.resize((224,224),Image.ANTIALIAS)).transpose(2,0,1)-meanValue.reshape(-1,1,1) 108 | label = np.zeros(7,dtype='int32') 109 | hot_id = int(Trn_label_list[np.where(Trn_label_list==dirs_Trn[index])[0],1][0]) 110 | label[hot_id-1] = label[hot_id-1]+1 111 | batch_input_x.append(img) 112 | batch_input_y.append(label) 113 | 114 | batch_input_x = np.asarray(batch_input_x) 115 | batch_input_y = np.asarray(batch_input_y,dtype='int32') 116 | loss_iter, error_iter = VGG16_CNN_model.train(batch_input_x,batch_input_y,lr) 117 | print('Epoch:%d, Iter:%d, TrainMinibatch: %i/%i, miniLoss:%f, miniTrainError: %f%%' % 118 | (epoch+1, iter, k+1, fold_batch*4, loss_iter, error_iter*100.)) 119 | 120 | 121 | if iter % 100 ==0: 122 | tst_loss =[] 123 | tst_error = [] 124 | for k in range(fold_batch): #41 125 | # load tst data 126 | batch_input_x = [] 127 | batch_input_y = [] 128 | for i in range(batchsize): #45 129 | index = k*batchsize + i 130 | img = Image.open('/home/trunk/disk1/lujiang/WDD/fold5/'+dirs_Tst[index]) 131 | img = np.array(img.resize((224,224),Image.ANTIALIAS)).transpose(2,0,1)-meanValue.reshape(-1,1,1) 132 | label = np.zeros(7,dtype='int32') 133 | hot_id = int(Tst_label_list[np.where(Tst_label_list==(dirs_Tst[index]))[0],1][0]) 134 | label[hot_id-1] = label[hot_id-1]+1 135 | batch_input_x.append(img) 136 | batch_input_y.append(label) 137 | 138 | batch_input_x = np.asarray(batch_input_x) 139 | batch_input_y = np.asarray(batch_input_y,dtype='int32') 140 | 141 | loss_iter, error_iter = VGG16_CNN_model.test(batch_input_x,batch_input_y) 142 | tst_loss.append(loss_iter) 143 | tst_error.append(error_iter) 144 | print('TestSet(Epoch:%d, Iter:%d) minibatch: %i/%i, miniTestError: %f%%' % 145 | (epoch+1, iter, k+1, fold_batch, error_iter*100.)) 146 | 147 | 148 | 149 | tst_loss = np.mean(np.asarray(tst_loss)) 150 | tst_error = np.mean(np.asarray(tst_error)) 151 | 152 | print('-------------------------------------------------------------------------------------') 153 | print('Epoch:%d, Iter:%d-- TestError:%f%%, TestLoss: %f' % 154 | (epoch+1, iter, tst_error*100., tst_loss)) 155 | print('-------------------------------------------------------------------------------------') 156 | 157 | # save the best model 158 | if tst_error < best_tst_error: 159 | best_tst_error = tst_error 160 | best_iter = iter 161 | current_tst_loss = tst_loss 162 | 163 | file = os.listdir('VGG16_CNN_tstfold5_1') 164 | if len(file)!=0: 165 | os.remove('VGG16_CNN_tstfold5_1/'+file[0]) 166 | 167 | model_file = 'VGG16_CNN_tstfold5_1/'+str(epoch+1)+'_'+str(iter)+'.h5' 168 | f = h5py.File(model_file) 169 | for p in VGG16_CNN_model.params: 170 | f[p.name] = p.get_value() 171 | f.close() 172 | 173 | 174 | print('Optimation complete.') 175 | print('Best test score of %f%% obtained at iteration %i, with test loss %f' % 176 | (best_tst_error*100., best_iter,current_tst_loss)) 177 | 178 | -------------------------------------------------------------------------------- /Codes/VGG16_FCN_Train.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | import os 4 | import numpy as np 5 | import h5py 6 | import pickle 7 | import matplotlib.pyplot as plt 8 | from VGG16_FCN import VGG16_FCN 9 | 10 | ## different random seeds 11 | rng = np.random.RandomState(23455) 12 | #rng = np.random.RandomState(1123) 13 | #rng = np.random.RandomState(564) 14 | #rng = np.random.RandomState(9852) 15 | 16 | ############################## 17 | #Loading pre-training params # 18 | ############################## 19 | print('...loading pre-training params') 20 | f = open('/home/trunk/disk1/lujiang/vgg16.pkl') 21 | VGG16model = pickle.load(f) 22 | f.close() 23 | W = VGG16model['param values'][0:26] 24 | meanValue = VGG16model['mean value'] 25 | 26 | 27 | ####################### 28 | ##### Build Model ##### 29 | ####################### 30 | print('...building the model') 31 | VGG16_FCN_model = VGG16_FCN(rng,weight=W, use_last_layer_weight=False) 32 | 33 | 34 | ####################### 35 | ##### Train Model ##### 36 | ####################### 37 | print('......training') 38 | 39 | batchsize = 2 40 | dirs_Trn = [] 41 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold1')) 42 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold2')) 43 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold3')) 44 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold4')) 45 | 46 | dirs_Tst = os.listdir('/home/trunk/disk1/lujiang/WDD/fold5') 47 | 48 | f1 = open('/home/trunk/disk1/lujiang/WDD/fold1_label.txt') 49 | f2 = open('/home/trunk/disk1/lujiang/WDD/fold2_label.txt') 50 | f3 = open('/home/trunk/disk1/lujiang/WDD/fold3_label.txt') 51 | f4 = open('/home/trunk/disk1/lujiang/WDD/fold4_label.txt') 52 | list1 = np.asarray([x.split() for x in f1.readlines()]) 53 | list2 = np.asarray([x.split() for x in f2.readlines()]) 54 | list3 = np.asarray([x.split() for x in f3.readlines()]) 55 | list4 = np.asarray([x.split() for x in f4.readlines()]) 56 | Trn_label_list = np.concatenate((list1,list2,list3,list4)) 57 | f1.close() 58 | f2.close() 59 | f3.close() 60 | f4.close() 61 | 62 | f = open('/home/trunk/disk1/lujiang/WDD/fold5_label.txt') 63 | Tst_label_list = np.asarray([x.split() for x in f.readlines()]) 64 | f.close() 65 | 66 | fold_batch = len(dirs_Tst) / batchsize 67 | 68 | n_epoch = 20 69 | base_lr = 0.00005 70 | best_tst_error = np.inf 71 | current_tst_loss = np.inf 72 | best_iter = 0 73 | 74 | for epoch in range(n_epoch): 75 | # learning rate for different epoch 76 | lr = 5** -(epoch/5) * base_lr 77 | print('*********** learning_rate: %f ************' % lr) 78 | 79 | for k in range(fold_batch*4): 80 | iter = fold_batch*4 * epoch + k +1 81 | # load train data 82 | batch_input_x = [] 83 | batch_input_y = [] 84 | 85 | if k < fold_batch: #fold-1 86 | for i in range(batchsize): 87 | index = k*batchsize + i 88 | img = plt.imread('/home/trunk/disk1/lujiang/WDD/fold1/'+dirs_Trn[index]).transpose(2,0,1)\ 89 | -meanValue.reshape(-1,1,1) 90 | label = np.zeros(7,dtype='int32') 91 | hot_id = int(Trn_label_list[np.where(Trn_label_list==dirs_Trn[index])[0],1][0]) 92 | label[hot_id-1] = label[hot_id-1]+1 93 | batch_input_x.append(img) 94 | batch_input_y.append(label) 95 | 96 | elif k < fold_batch*2: #fold-2 97 | for i in range(batchsize): 98 | index = k*batchsize + i 99 | img = plt.imread('/home/trunk/disk1/lujiang/WDD/fold2/'+dirs_Trn[index]).transpose(2,0,1)\ 100 | -meanValue.reshape(-1,1,1) 101 | label = np.zeros(7,dtype='int32') 102 | hot_id = int(Trn_label_list[np.where(Trn_label_list==dirs_Trn[index])[0],1][0]) 103 | label[hot_id-1] = label[hot_id-1]+1 104 | batch_input_x.append(img) 105 | batch_input_y.append(label) 106 | 107 | elif k < fold_batch*3: #fold-3 108 | for i in range(batchsize): 109 | index = k*batchsize + i 110 | img = plt.imread('/home/trunk/disk1/lujiang/WDD/fold3/'+dirs_Trn[index]).transpose(2,0,1)\ 111 | -meanValue.reshape(-1,1,1) 112 | label = np.zeros(7,dtype='int32') 113 | hot_id = int(Trn_label_list[np.where(Trn_label_list==dirs_Trn[index])[0],1][0]) 114 | label[hot_id-1] = label[hot_id-1]+1 115 | batch_input_x.append(img) 116 | batch_input_y.append(label) 117 | 118 | else : #fold-4 119 | for i in range(batchsize): 120 | index = k*batchsize + i 121 | img = plt.imread('/home/trunk/disk1/lujiang/WDD/fold4/'+dirs_Trn[index]).transpose(2,0,1)\ 122 | -meanValue.reshape(-1,1,1) 123 | label = np.zeros(7,dtype='int32') 124 | hot_id = int(Trn_label_list[np.where(Trn_label_list==dirs_Trn[index])[0],1][0]) 125 | label[hot_id-1] = label[hot_id-1]+1 126 | batch_input_x.append(img) 127 | batch_input_y.append(label) 128 | 129 | batch_input_x = np.asarray(batch_input_x) 130 | batch_input_y = np.asarray(batch_input_y,dtype='int32') 131 | loss_iter, error_iter = VGG16_FCN_model.train(batch_input_x,batch_input_y,lr) 132 | print('Epoch:%d, Iter:%d, TrainMinibatch: %i/%i, miniLoss:%f, miniTrainError: %f%%' % 133 | (epoch+1, iter, k+1, fold_batch*4, loss_iter, error_iter*100.)) 134 | 135 | if iter % 1000 ==0: 136 | tst_loss =[] 137 | tst_error = [] 138 | for k in range(fold_batch): 139 | # load tst data 140 | batch_input_x = [] 141 | batch_input_y = [] 142 | for i in range(batchsize): 143 | index = k*batchsize + i 144 | img = plt.imread('/home/trunk/disk1/lujiang/WDD/fold5/'+dirs_Tst[index]).transpose(2,0,1)\ 145 | -meanValue.reshape(-1,1,1) 146 | label = np.zeros(7,dtype='int32') 147 | hot_id = int(Tst_label_list[np.where(Tst_label_list==(dirs_Tst[index]))[0],1][0]) 148 | label[hot_id-1] = label[hot_id-1]+1 149 | batch_input_x.append(img) 150 | batch_input_y.append(label) 151 | 152 | batch_input_x = np.asarray(batch_input_x) 153 | batch_input_y = np.asarray(batch_input_y,dtype='int32') 154 | 155 | loss_iter, error_iter = VGG16_FCN_model.test(batch_input_x,batch_input_y) 156 | tst_loss.append(loss_iter) 157 | tst_error.append(error_iter) 158 | print('TestSet(Epoch:%d, Iter:%d) minibatch: %i/%i, miniTestError: %f%%' % 159 | (epoch+1, iter, k+1, fold_batch, error_iter*100.)) 160 | 161 | 162 | 163 | tst_loss = np.mean(np.asarray(tst_loss)) 164 | tst_error = np.mean(np.asarray(tst_error)) 165 | 166 | print('-------------------------------------------------------------------------------------') 167 | print('Epoch:%d, Iter:%d-- TestError:%f%%, TestLoss: %f' % 168 | (epoch+1, iter, tst_error*100., tst_loss)) 169 | print('-------------------------------------------------------------------------------------') 170 | 171 | 172 | # save the best model 173 | if tst_error < best_tst_error: 174 | best_tst_error = tst_error 175 | best_iter = iter 176 | current_tst_loss = tst_loss 177 | 178 | 179 | model_file = 'VGG16_Mean_tstfold5_1/'+str(epoch+1)+'_'+str(iter)+'.h5' 180 | f = h5py.File(model_file) 181 | for p in VGG16_FCN_model.params: 182 | f[p.name] = p.get_value() 183 | f.close() 184 | 185 | 186 | print('Optimation complete.') 187 | print('Best test score of %f%% obtained at iteration %i, with test loss %f' % 188 | (best_tst_error*100., best_iter,current_tst_loss)) 189 | -------------------------------------------------------------------------------- /Codes/VGG_S_FCN_Train.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | import os 4 | import numpy as np 5 | import h5py 6 | import pickle 7 | import matplotlib.pyplot as plt 8 | import os 9 | from VGG_S_FCN import VGG_S_FCN 10 | 11 | ## different random seeds 12 | rng = np.random.RandomState(23455) 13 | #rng = np.random.RandomState(1123) 14 | #rng = np.random.RandomState(564) 15 | #rng = np.random.RandomState(9852) 16 | 17 | ############################## 18 | #Loading pre-training params # 19 | ############################## 20 | print('...loading pre-training params') 21 | f = open('/home/trunk/disk1/lujiang/vgg_cnn_s.pkl') 22 | VGGSmodel = pickle.load(f) 23 | f.close() 24 | W = VGGSmodel['values'][0:10] 25 | meanValue = VGGSmodel['mean image'].mean(axis=1).mean(axis=1) 26 | 27 | 28 | ####################### 29 | ##### Build Model ##### 30 | ####################### 31 | print('...building the model') 32 | VGG_S_FCNmodel = VGG_S_FCN(rng,weight=W, use_last_layer_weight=False) 33 | 34 | 35 | ####################### 36 | ##### Train Model ##### 37 | ####################### 38 | print('......training') 39 | 40 | batchsize = 2 41 | dirs_Trn = [] 42 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold1')) 43 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold2')) 44 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold3')) 45 | dirs_Trn.extend(os.listdir('/home/trunk/disk1/lujiang/WDD/fold4')) 46 | 47 | dirs_Tst = os.listdir('/home/trunk/disk1/lujiang/WDD/fold5') 48 | 49 | f1 = open('/home/trunk/disk1/lujiang/WDD/fold1_label.txt') 50 | f2 = open('/home/trunk/disk1/lujiang/WDD/fold2_label.txt') 51 | f3 = open('/home/trunk/disk1/lujiang/WDD/fold3_label.txt') 52 | f4 = open('/home/trunk/disk1/lujiang/WDD/fold4_label.txt') 53 | list1 = np.asarray([x.split() for x in f1.readlines()]) 54 | list2 = np.asarray([x.split() for x in f2.readlines()]) 55 | list3 = np.asarray([x.split() for x in f3.readlines()]) 56 | list4 = np.asarray([x.split() for x in f4.readlines()]) 57 | Trn_label_list = np.concatenate((list1,list2,list3,list4)) 58 | f1.close() 59 | f2.close() 60 | f3.close() 61 | f4.close() 62 | 63 | f = open('/home/trunk/disk1/lujiang/WDD/fold5_label.txt') 64 | Tst_label_list = np.asarray([x.split() for x in f.readlines()]) 65 | f.close() 66 | 67 | fold_batch = len(dirs_Tst) / batchsize 68 | 69 | n_epoch = 20 70 | base_lr = 0.00005 71 | best_tst_error = np.inf 72 | current_tst_loss = np.inf 73 | best_iter = 0 74 | 75 | for epoch in range(n_epoch): 76 | # learning rate for different epoch 77 | lr = 5** -(epoch/5) * base_lr 78 | print('*********** learning_rate: %f ************' % lr) 79 | 80 | for k in range(fold_batch*4): 81 | iter = fold_batch*4 * epoch + k +1 82 | # load train data 83 | batch_input_x = [] 84 | batch_input_y = [] 85 | 86 | if k < fold_batch: #fold-1 87 | for i in range(batchsize): 88 | index = k*batchsize + i 89 | img = plt.imread('/home/trunk/disk1/lujiang/WDD/fold1/'+dirs_Trn[index]).transpose(2,0,1)\ 90 | -meanValue.reshape(-1,1,1) 91 | label = np.zeros(7,dtype='int32') 92 | hot_id = int(Trn_label_list[np.where(Trn_label_list==dirs_Trn[index])[0],1][0]) 93 | label[hot_id-1] = label[hot_id-1]+1 94 | batch_input_x.append(img) 95 | batch_input_y.append(label) 96 | 97 | elif k < fold_batch*2: #fold-2 98 | for i in range(batchsize): 99 | index = k*batchsize + i 100 | img = plt.imread('/home/trunk/disk1/lujiang/WDD/fold2/'+dirs_Trn[index]).transpose(2,0,1)\ 101 | -meanValue.reshape(-1,1,1) 102 | label = np.zeros(7,dtype='int32') 103 | hot_id = int(Trn_label_list[np.where(Trn_label_list==dirs_Trn[index])[0],1][0]) 104 | label[hot_id-1] = label[hot_id-1]+1 105 | batch_input_x.append(img) 106 | batch_input_y.append(label) 107 | 108 | elif k < fold_batch*3: #fold-3 109 | for i in range(batchsize): 110 | index = k*batchsize + i 111 | img = plt.imread('/home/trunk/disk1/lujiang/WDD/fold3/'+dirs_Trn[index]).transpose(2,0,1)\ 112 | -meanValue.reshape(-1,1,1) 113 | label = np.zeros(7,dtype='int32') 114 | hot_id = int(Trn_label_list[np.where(Trn_label_list==dirs_Trn[index])[0],1][0]) 115 | label[hot_id-1] = label[hot_id-1]+1 116 | batch_input_x.append(img) 117 | batch_input_y.append(label) 118 | 119 | else : #fold-4 120 | for i in range(batchsize): 121 | index = k*batchsize + i 122 | img = plt.imread('/home/trunk/disk1/lujiang/WDD/fold4/'+dirs_Trn[index]).transpose(2,0,1)\ 123 | -meanValue.reshape(-1,1,1) 124 | label = np.zeros(7,dtype='int32') 125 | hot_id = int(Trn_label_list[np.where(Trn_label_list==dirs_Trn[index])[0],1][0]) 126 | label[hot_id-1] = label[hot_id-1]+1 127 | batch_input_x.append(img) 128 | batch_input_y.append(label) 129 | 130 | batch_input_x = np.asarray(batch_input_x) 131 | batch_input_y = np.asarray(batch_input_y,dtype='int32') 132 | loss_iter, error_iter = VGG_S_FCNmodel.train(batch_input_x,batch_input_y,lr) 133 | print('Epoch:%d, Iter:%d, TrainMinibatch: %i/%i, miniLoss:%f, miniTrainError: %f%%' % 134 | (epoch+1, iter, k+1, fold_batch*4, loss_iter, error_iter*100.)) 135 | 136 | if iter % 1000 ==0: 137 | tst_loss =[] 138 | tst_error = [] 139 | for k in range(fold_batch): 140 | # load tst data 141 | batch_input_x = [] 142 | batch_input_y = [] 143 | for i in range(batchsize): 144 | index = k*batchsize + i 145 | img = plt.imread('/home/trunk/disk1/lujiang/WDD/fold5/'+dirs_Tst[index]).transpose(2,0,1)\ 146 | -meanValue.reshape(-1,1,1) 147 | label = np.zeros(7,dtype='int32') 148 | hot_id = int(Tst_label_list[np.where(Tst_label_list==(dirs_Tst[index]))[0],1][0]) 149 | label[hot_id-1] = label[hot_id-1]+1 150 | batch_input_x.append(img) 151 | batch_input_y.append(label) 152 | 153 | batch_input_x = np.asarray(batch_input_x) 154 | batch_input_y = np.asarray(batch_input_y,dtype='int32') 155 | 156 | loss_iter, error_iter= VGG_S_FCNmodel.test(batch_input_x,batch_input_y) 157 | tst_loss.append(loss_iter) 158 | tst_error.append(error_iter) 159 | print('TestSet(Epoch:%d, Iter:%d) minibatch: %i/%i, miniTestError: %f%%' % 160 | (epoch+1, iter, k+1, fold_batch, error_iter*100.)) 161 | 162 | 163 | 164 | tst_loss = np.mean(np.asarray(tst_loss)) 165 | tst_error = np.mean(np.asarray(tst_error)) 166 | 167 | print('-------------------------------------------------------------------------------------') 168 | print('Epoch:%d, Iter:%d-- TestError:%f%%, TestLoss: %f' % 169 | (epoch+1, iter, tst_error*100., tst_loss)) 170 | print('-------------------------------------------------------------------------------------') 171 | 172 | 173 | # save the best model 174 | if tst_error < best_tst_error: 175 | best_tst_error = tst_error 176 | best_iter = iter 177 | current_tst_loss = tst_loss 178 | 179 | file = os.listdir('VGG_S_Mean_tstfold5_1') 180 | if len(file)!=0: 181 | os.remove('VGG_S_Mean_tstfold5_1/'+file[0]) 182 | 183 | model_file = 'VGG_S_Mean_tstfold5_1/'+str(epoch+1)+'_'+str(iter)+'.h5' 184 | f = h5py.File(model_file) 185 | for p in VGG_S_FCNmodel.params: 186 | f[p.name] = p.get_value() 187 | f.close() 188 | 189 | 190 | print('Optimation complete.') 191 | print('Best test score of %f%% obtained at iteration %i, with test loss %f' % 192 | (best_tst_error*100., best_iter,current_tst_loss)) 193 | -------------------------------------------------------------------------------- /Codes/VGG_S_FCN_Detection.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | import os 4 | import numpy as np 5 | import h5py 6 | import skimage.measure 7 | import matplotlib.patches as mpatches 8 | import pickle 9 | import matplotlib.pyplot as plt 10 | 11 | import matplotlib 12 | import cv2 13 | from VGG16_FCN import VGG16_FCN 14 | from VGG_S_FCN import VGG_S_FCN 15 | 16 | rng = np.random.RandomState(23455) 17 | 18 | ############################## 19 | #Loading pre-training params # 20 | ############################## 21 | print('...loading pre-training params') 22 | f = open('/home/trunk/disk1/lujiang/vgg_cnn_s.pkl') 23 | VGGSmodel = pickle.load(f) 24 | f.close() 25 | W = VGGSmodel['values'][0:10] 26 | meanValue = VGGSmodel['mean image'].mean(axis=1).mean(axis=1) 27 | 28 | classname = ['Powdery Mildew','Smut','Black Chaff', 'Stripe Rust', 'Leaf Blotch', 'Leaf Rust','Healthy'] 29 | show_factor =0.8 # clip the border arround 30 | area_threshold = 20000 # restrain the small area 31 | binary_threshold= 0.9 # binary image threshold 32 | 33 | f = h5py.File('VGG_S_soft_tstfold5_1/8_28000.h5') 34 | W1 = f['Conv1#W'][:] 35 | b1 = f['Conv1#b'][:] 36 | W2 = f['Conv2#W'][:] 37 | b2 = f['Conv2#b'][:] 38 | W3 = f['Conv3#W'][:] 39 | b3 = f['Conv3#b'][:] 40 | W4 = f['Conv4#W'][:] 41 | b4 = f['Conv4#b'][:] 42 | W5 = f['Conv5#W'][:] 43 | b5 = f['Conv5#b'][:] 44 | W6 = f['Conv6#W'][:] 45 | b6 = f['Conv6#b'][:] 46 | W7 = f['Conv7#W'][:] 47 | b7 = f['Conv7#b'][:] 48 | W8 = f['Aggregation8#W'][:] 49 | b8 = f['Aggregation8#b'][:] 50 | f.close() 51 | 52 | W_soft = [W1,b1,W2,b2,W3,b3,W4,b4,W5,b5,W6,b6,W7,b7,W8,b8] 53 | 54 | 55 | f = h5py.File('VGG_S_Hard_tstfold5_1/8_27000.h5') 56 | W1 = f['Conv1#W'][:] 57 | b1 = f['Conv1#b'][:] 58 | W2 = f['Conv2#W'][:] 59 | b2 = f['Conv2#b'][:] 60 | W3 = f['Conv3#W'][:] 61 | b3 = f['Conv3#b'][:] 62 | W4 = f['Conv4#W'][:] 63 | b4 = f['Conv4#b'][:] 64 | W5 = f['Conv5#W'][:] 65 | b5 = f['Conv5#b'][:] 66 | W6 = f['Conv6#W'][:] 67 | b6 = f['Conv6#b'][:] 68 | W7 = f['Conv7#W'][:] 69 | b7 = f['Conv7#b'][:] 70 | W8 = f['Aggregation8#W'][:] 71 | b8 = f['Aggregation8#b'][:] 72 | f.close() 73 | 74 | W_max = [W1,b1,W2,b2,W3,b3,W4,b4,W5,b5,W6,b6,W7,b7,W8,b8] 75 | 76 | 77 | f = h5py.File('VGG_S_Mean_tstfold5_1/14_48000.h5') 78 | W1 = f['Conv1#W'][:] 79 | b1 = f['Conv1#b'][:] 80 | W2 = f['Conv2#W'][:] 81 | b2 = f['Conv2#b'][:] 82 | W3 = f['Conv3#W'][:] 83 | b3 = f['Conv3#b'][:] 84 | W4 = f['Conv4#W'][:] 85 | b4 = f['Conv4#b'][:] 86 | W5 = f['Conv5#W'][:] 87 | b5 = f['Conv5#b'][:] 88 | W6 = f['Conv6#W'][:] 89 | b6 = f['Conv6#b'][:] 90 | W7 = f['Conv7#W'][:] 91 | b7 = f['Conv7#b'][:] 92 | W8 = f['Aggregation8#W'][:] 93 | b8 = f['Aggregation8#b'][:] 94 | f.close() 95 | 96 | W_avg = [W1,b1,W2,b2,W3,b3,W4,b4,W5,b5,W6,b6,W7,b7,W8,b8] 97 | 98 | 99 | ####################### 100 | ##### Build Model ##### 101 | ####################### 102 | print('...building the model') 103 | model_soft = VGG_S_FCN(rng,weight=W_soft, use_last_layer_weight=True,agg_func='soft') 104 | model_max = VGG_S_FCN(rng,weight=W_max, use_last_layer_weight=True,agg_func='max') 105 | model_avg = VGG_S_FCN(rng,weight=W_avg, use_last_layer_weight=True,agg_func='avg') 106 | 107 | 108 | ####################### 109 | ##### Test Model ##### 110 | ####################### 111 | print('......test') 112 | 113 | # try random sequence display 114 | batchsize = 1 115 | dirs_test = os.listdir('WDD/fold5/') 116 | 117 | # read label 118 | f = open('WDD/fold5_label.txt') 119 | tst_label_list = np.asarray([x.split() for x in f.readlines()]) 120 | f.close() 121 | 122 | # score_size = (832-224)/32+1 123 | 124 | 125 | test_error_soft = [] 126 | test_error_max = [] 127 | test_error_avg = [] 128 | 129 | soft_error_list = open('soft_error_list_s.txt','a') 130 | max_error_list = open('max_error_list_s.txt','a') 131 | avg_error_list = open('avg_error_list_s.txt','a') 132 | for index in range(len(dirs_test)): 133 | print(index+1) 134 | # load tst data 135 | x = [] 136 | y = [] 137 | img_org = plt.imread('WDD/fold5/'+dirs_test[index]) 138 | img = img_org.transpose(2,0,1)-meanValue.reshape(-1,1,1) 139 | label = np.zeros(7,dtype='int32') 140 | hot_id = int(tst_label_list[np.where(tst_label_list==(dirs_test[index]))[0],1][0]) 141 | label[hot_id-1] = label[hot_id-1]+1 142 | 143 | batch_input_x = np.asarray(x.append(img)) 144 | batch_input_y = np.asarray(y.append(label)) 145 | 146 | prediction_soft, tst_error_soft, pro_soft, pro_bag_soft = model_soft.detection(x,y) 147 | prediction_max, tst_error_max, pro_max, pro_bag_max = model_max.detection(x, y) 148 | prediction_avg, tst_error_avg, pro_avg, pro_bag_avg = model_avg.detection(x, y) 149 | 150 | if tst_error_soft>0: 151 | soft_error_list.write(dirs_test[index]+"\n") 152 | if tst_error_max>0: 153 | max_error_list.write(dirs_test[index]+"\n") 154 | if tst_error_avg>0: 155 | avg_error_list.write(dirs_test[index]+"\n") 156 | 157 | test_error_soft.append(tst_error_soft) 158 | test_error_max.append(tst_error_max) 159 | test_error_avg.append(tst_error_avg) 160 | print('tst_img/'+dirs_test[index]+'---test number: %i,Soft Error: %f%%' %( index+1, tst_error_soft*100.)) 161 | print('tst_img/' + dirs_test[index] + '---test number: %i,Max Error: %f%%' % (index + 1, tst_error_max * 100.)) 162 | print('tst_img/' + dirs_test[index] + '---test number: %i,Avg Error: %f%%' % (index + 1, tst_error_avg * 100.)) 163 | 164 | fig = plt.figure() 165 | 166 | plt.imshow(img_org) 167 | plt.axis('off') 168 | 169 | # box approximation by opencv findContours: soft 170 | prediction_map_soft = cv2.resize(pro_soft[:,prediction_soft,:,:].squeeze(),(832,832),interpolation=cv2.INTER_CUBIC) 171 | re,prediction_map_BW_soft = cv2.threshold(prediction_map_soft,binary_threshold,1,cv2.THRESH_BINARY) 172 | prediction_map_BW_soft = np.asarray(prediction_map_BW_soft,dtype=np.uint8) 173 | _, contours, _ = cv2.findContours(prediction_map_BW_soft,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) 174 | for i in range(len(contours)): 175 | box = cv2.boundingRect(contours[i]) 176 | box_area = box[2]*box[3] 177 | if box_area > area_threshold: 178 | w_bias = int(box[2]*(1-show_factor)*0.5) 179 | h_bias = int(box[3]*(1-show_factor)*0.5) 180 | w = int(box[2]*show_factor) 181 | h = int(box[3]*show_factor) 182 | rect = mpatches.Rectangle((box[0]+w_bias,box[1]+h_bias),w,h,fill=False,edgecolor='springgreen',linewidth=2) 183 | plt.gca().add_patch(rect) 184 | plt.text(box[0]+70,box[1]+70,classname[prediction_soft[0]], size = 6, 185 | family = "Times New Roman", color = "black", style = "italic", 186 | bbox = dict(facecolor = "springgreen", alpha = 1)) 187 | 188 | img_soft = img_org[:, :, 0] * prediction_map_soft 189 | plt.imsave('WDD_save_s/'+dirs_test[index]+'_soft_'+classname[prediction_soft[0]]+'.eps',img_soft) 190 | # ax[1].imshow(img_soft) 191 | 192 | 193 | 194 | # box approximation by opencv findContours: max 195 | prediction_map_max = cv2.resize(pro_max[:,prediction_max,:,:].squeeze(),(832,832),interpolation=cv2.INTER_CUBIC) 196 | re, prediction_map_BW_max = cv2.threshold(prediction_map_max,binary_threshold,1,cv2.THRESH_BINARY) 197 | prediction_map_BW_max = np.asarray(prediction_map_BW_max,dtype=np.uint8) 198 | _, contours, _ = cv2.findContours(prediction_map_BW_max,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) 199 | for i in range(len(contours)): 200 | box = cv2.boundingRect(contours[i]) 201 | box_area = box[2]*box[3] 202 | if box_area > area_threshold/3: 203 | w_bias = int(box[2]*(1-0.9)*0.5) 204 | h_bias = int(box[3]*(1-0.9)*0.5) 205 | w = int(box[2]*show_factor) 206 | h = int(box[3]*show_factor) 207 | rect = mpatches.Rectangle((box[0]+w_bias,box[1]+h_bias),w,h,fill=False,edgecolor='pink',linewidth=2) 208 | plt.gca().add_patch(rect) 209 | plt.text(box[0]+30,box[1]+20,classname[prediction_max[0]], size = 6, 210 | family = "Times New Roman", color = "black", style = "italic", 211 | bbox = dict(facecolor = "pink", alpha = 1)) 212 | img_max = img_org[:, :, 0] * prediction_map_max 213 | plt.imsave('WDD_save_s/'+dirs_test[index]+'_max_'+classname[prediction_max[0]]+'.eps',img_max) 214 | # ax[2].imshow(img_max) 215 | 216 | 217 | 218 | # box approximation by opencv findContours: avg 219 | prediction_map_avg = cv2.resize(pro_avg[:,prediction_avg,:,:].squeeze(),(832,832),interpolation=cv2.INTER_CUBIC) 220 | re, prediction_map_BW_avg = cv2.threshold(prediction_map_avg,binary_threshold,1,cv2.THRESH_BINARY) 221 | prediction_map_BW_avg = np.asarray(prediction_map_BW_avg,dtype=np.uint8) 222 | _, contours, _ = cv2.findContours(prediction_map_BW_avg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 223 | for i in range(len(contours)): 224 | box = cv2.boundingRect(contours[i]) 225 | box_area = box[2]*box[3] 226 | if box_area > area_threshold: 227 | w_bias = int(box[2]*(1-show_factor)*0.5) 228 | h_bias = int(box[3]*(1-show_factor)*0.5) 229 | w = int(box[2]*show_factor) 230 | h = int(box[3]*show_factor) 231 | rect = mpatches.Rectangle((box[0]+w_bias,box[1]+h_bias),w,h,fill=False,edgecolor='lightblue',linewidth=2) 232 | plt.gca().add_patch(rect) 233 | plt.text(box[0]+70,box[1]+70,classname[prediction_avg[0]], size = 6, 234 | family = "Times New Roman", color = "black", style = "italic", 235 | bbox = dict(facecolor = "lightblue", alpha = 1)) 236 | img_avg = img_org[:, :, 0] * prediction_map_avg 237 | plt.imsave('WDD_save_s/'+dirs_test[index]+'_avg_'+classname[prediction_avg[0]]+'.eps',img_avg) 238 | fig.savefig('WDD_save_s/'+dirs_test[index]+'.eps',bbox_inches='tight', pad_inches=0.0, format='eps') 239 | # ax[3].imshow(img_avg) 240 | # plt.show() 241 | 242 | 243 | test_error_soft = np.mean(np.asarray(test_error_soft)) 244 | test_error_max = np.mean(np.asarray(test_error_max)) 245 | test_error_avg = np.mean(np.asarray(test_error_avg)) 246 | soft_error_list.close() 247 | max_error_list.close() 248 | avg_error_list.close() 249 | print('Test complete.') 250 | print('Total test error is %f%%,%f%%,%f%%' % (test_error_soft*100.,test_error_max*100.,test_error_avg*100.)) -------------------------------------------------------------------------------- /Codes/VGG16_FCN_Detection.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | __author__ = 'jianglu' 3 | import os 4 | import numpy as np 5 | import h5py 6 | import skimage.measure 7 | import matplotlib.patches as mpatches 8 | import pickle 9 | import matplotlib.pyplot as plt 10 | 11 | import matplotlib 12 | import cv2 13 | from VGG16_FCN import VGG16_FCN 14 | from VGG_S_FCN import VGG_S_FCN 15 | 16 | rng = np.random.RandomState(23455) 17 | 18 | ############################## 19 | #Loading pre-training params # 20 | ############################## 21 | print('...loading pre-training params') 22 | f = open('/home/trunk/disk1/lujiang/vgg16.pkl') 23 | VGG16model = pickle.load(f) 24 | meanValue = VGG16model['mean value'] 25 | f.close() 26 | 27 | classname = ['Powdery Mildew','Smut','Black Chaff', 'Stripe Rust', 'Leaf Blotch', 'Leaf Rust','Healthy'] 28 | show_factor =0.8 # clip the border arround 29 | area_threshold = 20000 # restrain the small area 30 | binary_threshold= 0.9 # binary image threshold 31 | 32 | f = h5py.File('VGG16_FCN_tstfold5_4/12_43000.h5') 33 | W1 = f['Conv1#W'][:] 34 | b1 = f['Conv1#b'][:] 35 | W2 = f['Conv2#W'][:] 36 | b2 = f['Conv2#b'][:] 37 | W3 = f['Conv3#W'][:] 38 | b3 = f['Conv3#b'][:] 39 | W4 = f['Conv4#W'][:] 40 | b4 = f['Conv4#b'][:] 41 | W5 = f['Conv5#W'][:] 42 | b5 = f['Conv5#b'][:] 43 | W6 = f['Conv6#W'][:] 44 | b6 = f['Conv6#b'][:] 45 | W7 = f['Conv7#W'][:] 46 | b7 = f['Conv7#b'][:] 47 | W8 = f['Conv8#W'][:] 48 | b8 = f['Conv8#b'][:] 49 | W9 = f['Conv9#W'][:] 50 | b9 = f['Conv9#b'][:] 51 | W10 = f['Conv10#W'][:] 52 | b10 = f['Conv10#b'][:] 53 | W11 = f['Conv11#W'][:] 54 | b11 = f['Conv11#b'][:] 55 | W12 = f['Conv12#W'][:] 56 | b12 = f['Conv12#b'][:] 57 | W13 = f['Conv13#W'][:] 58 | b13 = f['Conv13#b'][:] 59 | W14 = f['Conv14#W'][:] 60 | b14 = f['Conv14#b'][:] 61 | W15 = f['Conv15#W'][:] 62 | b15 = f['Conv15#b'][:] 63 | W16 = f['Aggregation16#W'][:] 64 | b16 = f['Aggregation16#b'][:] 65 | f.close() 66 | 67 | W_soft = [W1,b1,W2,b2,W3,b3,W4,b4,W5,b5,W6,b6,W7,b7,W8,b8,W9,b9,W10,b10,W11, 68 | b11,W12,b12,W13,b13,W14,b14,W15,b15,W16,b16] 69 | 70 | 71 | f = h5py.File('VGG16_Hard_tstfold5_1/8_29000.h5') 72 | W1 = f['Conv1#W'][:] 73 | b1 = f['Conv1#b'][:] 74 | W2 = f['Conv2#W'][:] 75 | b2 = f['Conv2#b'][:] 76 | W3 = f['Conv3#W'][:] 77 | b3 = f['Conv3#b'][:] 78 | W4 = f['Conv4#W'][:] 79 | b4 = f['Conv4#b'][:] 80 | W5 = f['Conv5#W'][:] 81 | b5 = f['Conv5#b'][:] 82 | W6 = f['Conv6#W'][:] 83 | b6 = f['Conv6#b'][:] 84 | W7 = f['Conv7#W'][:] 85 | b7 = f['Conv7#b'][:] 86 | W8 = f['Conv8#W'][:] 87 | b8 = f['Conv8#b'][:] 88 | W9 = f['Conv9#W'][:] 89 | b9 = f['Conv9#b'][:] 90 | W10 = f['Conv10#W'][:] 91 | b10 = f['Conv10#b'][:] 92 | W11 = f['Conv11#W'][:] 93 | b11 = f['Conv11#b'][:] 94 | W12 = f['Conv12#W'][:] 95 | b12 = f['Conv12#b'][:] 96 | W13 = f['Conv13#W'][:] 97 | b13 = f['Conv13#b'][:] 98 | W14 = f['Conv14#W'][:] 99 | b14 = f['Conv14#b'][:] 100 | W15 = f['Conv15#W'][:] 101 | b15 = f['Conv15#b'][:] 102 | W16 = f['Aggregation16#W'][:] 103 | b16 = f['Aggregation16#b'][:] 104 | f.close() 105 | 106 | W_max = [W1,b1,W2,b2,W3,b3,W4,b4,W5,b5,W6,b6,W7,b7,W8,b8,W9,b9,W10,b10,W11, 107 | b11,W12,b12,W13,b13,W14,b14,W15,b15,W16,b16] 108 | 109 | f = h5py.File('VGG16_Mean_tstfold5_1/10_36000.h5') 110 | W1 = f['Conv1#W'][:] 111 | b1 = f['Conv1#b'][:] 112 | W2 = f['Conv2#W'][:] 113 | b2 = f['Conv2#b'][:] 114 | W3 = f['Conv3#W'][:] 115 | b3 = f['Conv3#b'][:] 116 | W4 = f['Conv4#W'][:] 117 | b4 = f['Conv4#b'][:] 118 | W5 = f['Conv5#W'][:] 119 | b5 = f['Conv5#b'][:] 120 | W6 = f['Conv6#W'][:] 121 | b6 = f['Conv6#b'][:] 122 | W7 = f['Conv7#W'][:] 123 | b7 = f['Conv7#b'][:] 124 | W8 = f['Conv8#W'][:] 125 | b8 = f['Conv8#b'][:] 126 | W9 = f['Conv9#W'][:] 127 | b9 = f['Conv9#b'][:] 128 | W10 = f['Conv10#W'][:] 129 | b10 = f['Conv10#b'][:] 130 | W11 = f['Conv11#W'][:] 131 | b11 = f['Conv11#b'][:] 132 | W12 = f['Conv12#W'][:] 133 | b12 = f['Conv12#b'][:] 134 | W13 = f['Conv13#W'][:] 135 | b13 = f['Conv13#b'][:] 136 | W14 = f['Conv14#W'][:] 137 | b14 = f['Conv14#b'][:] 138 | W15 = f['Conv15#W'][:] 139 | b15 = f['Conv15#b'][:] 140 | W16 = f['Aggregation16#W'][:] 141 | b16 = f['Aggregation16#b'][:] 142 | f.close() 143 | 144 | W_avg = [W1,b1,W2,b2,W3,b3,W4,b4,W5,b5,W6,b6,W7,b7,W8,b8,W9,b9,W10,b10,W11, 145 | b11,W12,b12,W13,b13,W14,b14,W15,b15,W16,b16] 146 | 147 | 148 | ####################### 149 | ##### Build Model ##### 150 | ####################### 151 | print('...building the model') 152 | model_soft = VGG16_FCN(rng,weight=W_soft, use_last_layer_weight=True,agg_func='soft') 153 | model_max = VGG16_FCN(rng,weight=W_max, use_last_layer_weight=True,agg_func='max') 154 | model_avg = VGG16_FCN(rng,weight=W_avg, use_last_layer_weight=True,agg_func='avg') 155 | 156 | 157 | ####################### 158 | ##### Test Model ##### 159 | ####################### 160 | print('......test') 161 | 162 | # try random sequence display 163 | batchsize = 1 164 | dirs_test = os.listdir('WDD/fold5/') 165 | 166 | # read label 167 | f = open('WDD/fold5_label.txt') 168 | tst_label_list = np.asarray([x.split() for x in f.readlines()]) 169 | f.close() 170 | 171 | # score_size = (832-224)/32+1 172 | 173 | 174 | test_error_soft = [] 175 | test_error_max = [] 176 | test_error_avg = [] 177 | 178 | soft_error_list = open('soft_error_list.txt','a') 179 | max_error_list = open('max_error_list.txt','a') 180 | avg_error_list = open('avg_error_list.txt','a') 181 | for index in range(len(dirs_test)): 182 | print(index+1) 183 | # load tst data 184 | x = [] 185 | y = [] 186 | img_org = plt.imread('WDD/fold5/'+dirs_test[index]) 187 | img = img_org.transpose(2,0,1)-meanValue.reshape(-1,1,1) 188 | label = np.zeros(7,dtype='int32') 189 | hot_id = int(tst_label_list[np.where(tst_label_list==(dirs_test[index]))[0],1][0]) 190 | label[hot_id-1] = label[hot_id-1]+1 191 | 192 | batch_input_x = np.asarray(x.append(img)) 193 | batch_input_y = np.asarray(y.append(label)) 194 | 195 | prediction_soft, tst_error_soft, pro_soft, pro_bag_soft = model_soft.detection(x,y) 196 | prediction_max, tst_error_max, pro_max, pro_bag_max = model_max.detection(x, y) 197 | prediction_avg, tst_error_avg, pro_avg, pro_bag_avg = model_avg.detection(x, y) 198 | 199 | if tst_error_soft>0: 200 | soft_error_list.write(dirs_test[index]+"\n") 201 | if tst_error_max>0: 202 | max_error_list.write(dirs_test[index]+"\n") 203 | if tst_error_avg>0: 204 | avg_error_list.write(dirs_test[index]+"\n") 205 | 206 | test_error_soft.append(tst_error_soft) 207 | test_error_max.append(tst_error_max) 208 | test_error_avg.append(tst_error_avg) 209 | print('tst_img/'+dirs_test[index]+'---test number: %i,Soft Error: %f%%' %( index+1, tst_error_soft*100.)) 210 | print('tst_img/' + dirs_test[index] + '---test number: %i,Max Error: %f%%' % (index + 1, tst_error_max * 100.)) 211 | print('tst_img/' + dirs_test[index] + '---test number: %i,Avg Error: %f%%' % (index + 1, tst_error_avg * 100.)) 212 | 213 | fig = plt.figure() 214 | 215 | plt.imshow(img_org) 216 | plt.axis('off') 217 | 218 | prediction_map_soft = cv2.resize(pro_soft[:,prediction_soft,:,:].squeeze(),(832,832),interpolation=cv2.INTER_CUBIC) 219 | re,prediction_map_BW_soft = cv2.threshold(prediction_map_soft,binary_threshold,1,cv2.THRESH_BINARY) 220 | prediction_map_BW_soft = np.asarray(prediction_map_BW_soft,dtype=np.uint8) 221 | _, contours, _ = cv2.findContours(prediction_map_BW_soft,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) 222 | for i in range(len(contours)): 223 | box = cv2.boundingRect(contours[i]) 224 | box_area = box[2]*box[3] 225 | if box_area > area_threshold: 226 | w_bias = int(box[2]*(1-show_factor)*0.5) 227 | h_bias = int(box[3]*(1-show_factor)*0.5) 228 | w = int(box[2]*show_factor) 229 | h = int(box[3]*show_factor) 230 | rect = mpatches.Rectangle((box[0]+w_bias,box[1]+h_bias),w,h,fill=False,edgecolor='springgreen',linewidth=2) 231 | plt.gca().add_patch(rect) 232 | plt.text(box[0]+70,box[1]+70,classname[prediction_soft[0]], size = 6, 233 | family = "Times New Roman", color = "black", style = "italic", 234 | bbox = dict(facecolor = "springgreen", alpha = 1)) 235 | 236 | img_soft = img_org[:, :, 0] * prediction_map_soft 237 | plt.imsave('WDD_save/'+dirs_test[index]+'_soft_'+classname[prediction_soft[0]]+'.eps',img_soft) 238 | # ax[1].imshow(img_soft) 239 | 240 | 241 | 242 | # box approximation by opencv findContours: max 243 | prediction_map_max = cv2.resize(pro_max[:,prediction_max,:,:].squeeze(),(832,832),interpolation=cv2.INTER_CUBIC) 244 | re, prediction_map_BW_max = cv2.threshold(prediction_map_max,binary_threshold,1,cv2.THRESH_BINARY) 245 | prediction_map_BW_max = np.asarray(prediction_map_BW_max,dtype=np.uint8) 246 | _, contours, _ = cv2.findContours(prediction_map_BW_max,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) 247 | for i in range(len(contours)): 248 | box = cv2.boundingRect(contours[i]) 249 | box_area = box[2]*box[3] 250 | if box_area > area_threshold/3: 251 | w_bias = int(box[2]*(1-0.9)*0.5) 252 | h_bias = int(box[3]*(1-0.9)*0.5) 253 | w = int(box[2]*show_factor) 254 | h = int(box[3]*show_factor) 255 | rect = mpatches.Rectangle((box[0]+w_bias,box[1]+h_bias),w,h,fill=False,edgecolor='pink',linewidth=2) 256 | plt.gca().add_patch(rect) 257 | plt.text(box[0]+30,box[1]+20,classname[prediction_max[0]], size = 6, 258 | family = "Times New Roman", color = "black", style = "italic", 259 | bbox = dict(facecolor = "pink", alpha = 1)) 260 | img_max = img_org[:, :, 0] * prediction_map_max 261 | plt.imsave('WDD_save/'+dirs_test[index]+'_max_'+classname[prediction_max[0]]+'.eps',img_max) 262 | # ax[2].imshow(img_max) 263 | 264 | 265 | 266 | # box approximation by opencv findContours: avg 267 | prediction_map_avg = cv2.resize(pro_avg[:,prediction_avg,:,:].squeeze(),(832,832),interpolation=cv2.INTER_CUBIC) 268 | re, prediction_map_BW_avg = cv2.threshold(prediction_map_avg,binary_threshold,1,cv2.THRESH_BINARY) 269 | prediction_map_BW_avg = np.asarray(prediction_map_BW_avg,dtype=np.uint8) 270 | _, contours, _ = cv2.findContours(prediction_map_BW_avg, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) 271 | for i in range(len(contours)): 272 | box = cv2.boundingRect(contours[i]) 273 | box_area = box[2]*box[3] 274 | if box_area > area_threshold: 275 | w_bias = int(box[2]*(1-show_factor)*0.5) 276 | h_bias = int(box[3]*(1-show_factor)*0.5) 277 | w = int(box[2]*show_factor) 278 | h = int(box[3]*show_factor) 279 | rect = mpatches.Rectangle((box[0]+w_bias,box[1]+h_bias),w,h,fill=False,edgecolor='lightblue',linewidth=2) 280 | plt.gca().add_patch(rect) 281 | plt.text(box[0]+70,box[1]+70,classname[prediction_avg[0]], size = 6, 282 | family = "Times New Roman", color = "black", style = "italic", 283 | bbox = dict(facecolor = "lightblue", alpha = 1)) 284 | img_avg = img_org[:, :, 0] * prediction_map_avg 285 | plt.imsave('WDD_save/'+dirs_test[index]+'_avg_'+classname[prediction_avg[0]]+'.eps',img_avg) 286 | fig.savefig('WDD_save/'+dirs_test[index]+'.eps',bbox_inches='tight', pad_inches=0.0, format='eps') 287 | # ax[3].imshow(img_avg) 288 | # plt.show() 289 | 290 | 291 | test_error_soft = np.mean(np.asarray(test_error_soft)) 292 | test_error_max = np.mean(np.asarray(test_error_max)) 293 | test_error_avg = np.mean(np.asarray(test_error_avg)) 294 | soft_error_list.close() 295 | max_error_list.close() 296 | avg_error_list.close() 297 | print('Test complete.') 298 | print('Total test error is %f%%,%f%%,%f%%' % (test_error_soft*100.,test_error_max*100.,test_error_avg*100.)) --------------------------------------------------------------------------------