~opencrea/+junk/market

« back to all changes in this revision

Viewing changes to ann/models/ann_network.py

  • Committer: joannes
  • Date: 2017-09-23 21:42:25 UTC
  • Revision ID: joannes@debian-20170923214225-0ez3b2juxo7lduii
convergent

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
##############################################################################
6
6
 
7
7
from odoo import tools
8
 
from odoo import models, fields, api
 
8
from odoo import models, fields, api, _
 
9
from odoo.exceptions import UserError
9
10
import requests
10
11
import os
11
12
import time
39
40
    output_value = fields.Char('Output Value')
40
41
    training_value = fields.Char('Training Value')
41
42
    layer_sizes = fields.Char('Layer Size')
 
43
 
 
44
    nb_input = fields.Integer('Number of Input')
 
45
    nb_output = fields.Integer('Number of Output')
 
46
    nb_hiden_layer = fields.Integer('Number of hidden layer')
 
47
 
42
48
    input_neuron_ids = fields.One2many('ann.neuron', 'network_id', string='Inputs', domain=[('layer_id.layer_type', '=', 'input')])
43
49
    output_neuron_ids = fields.One2many('ann.neuron', 'network_id', string='Ouputs', domain=[('layer_id.layer_type', '=', 'output')])
44
50
 
53
59
        string='Status', required=True, default='draft')
54
60
 
55
61
    @api.multi
 
62
    def unlink(self):
 
63
        for network in self:
 
64
            layer_ids = network.input_layer_id | network.output_layer_id | network.hidden_layer_ids
 
65
            for layer in layer_ids:
 
66
                for neuron in layer.neuron_ids:
 
67
                    neuron.input_connection_ids.unlink()
 
68
                    neuron.output_connection_ids.unlink()
 
69
                layer.neuron_ids.unlink()
 
70
        return super(AnnNetwork, self).unlink()
 
71
 
 
72
    @api.multi
56
73
    def button_init_ann(self):
57
74
        "Unlink All Network configuration"
58
75
        for network in self:
78
95
        return res
79
96
 
80
97
    @api.multi
 
98
    def unlink_connection(self):
 
99
        "Order Network layer"
 
100
        for network in self:
 
101
            for layer in network.hidden_layer_ids:
 
102
                #unlink one connection by neuron to unstable the error
 
103
                next_layer_nb_neuron = len(layer.next_layer_id.neuron_ids)
 
104
                for i in range(len(layer.neuron_ids)):
 
105
                    if i < next_layer_nb_neuron:
 
106
                        condition = [
 
107
                            ('to_neuron_id', '=', layer.neuron_ids[i].id),
 
108
                            ('from_neuron_id', '=', layer.next_layer_id.neuron_ids[i].id)
 
109
                            ]
 
110
 
 
111
                        connection_ids = self.env['ann.connection'].search(condition)
 
112
                        for connection in connection_ids:
 
113
                            connection.unlink()
 
114
 
 
115
    @api.multi
81
116
    def order_layer(self):
82
117
        "Order Network layer"
83
118
        def order_neuron(layer):
120
155
                        input_neuron.input_value = float(input_value.pop())
121
156
                    else:
122
157
                        input_neuron.input_value = 0.0
 
158
 
 
159
            layer.neuron_ids.button_run()
 
160
 
123
161
            while layer.next_layer_id:
124
162
                layer.neuron_ids.button_run()
125
163
                layer = layer.next_layer_id
 
164
 
126
165
            output_value = ''
127
166
            layer.neuron_ids.button_run()
128
167
            for output_neuron in layer.neuron_ids:
129
168
                output_value += "%s " % (output_neuron.output_value)
130
 
            network.output_value = output_value
131
 
 
132
 
    @api.multi
 
169
 
 
170
            network.output_value = output_value.strip()
 
171
 
 
172
    @api.multi
 
173
    def button_backforward_error(self):
 
174
        "Backforward the error on the Network"
 
175
 
 
176
        #propagation on each layer
 
177
        for network in self:
 
178
            layer = network.output_layer_id
 
179
            if network.training_value:
 
180
                #Calculate the output error
 
181
                train_value_list = list(reversed(network.training_value.strip().split(' ')))
 
182
                for output_neuron in layer.neuron_ids:
 
183
                    if len(train_value_list):
 
184
                        train_value = train_value_list.pop()
 
185
                        if train_value:
 
186
                            output_neuron.real_value = float(train_value)
 
187
 
 
188
            #Calculate error on output neuron
 
189
            layer.button_train()
 
190
 
 
191
            #Progagate error on all layer
 
192
            while layer.previous_layer_id:
 
193
                layer = layer.previous_layer_id
 
194
                layer.button_train()
 
195
 
 
196
 
 
197
 
 
198
    @api.multi
 
199
    def button_init_weight(self):
 
200
        "Run Network"
 
201
        for network in self:
 
202
            connection_ids = self.env['ann.connection'].search([('network_id', '=', network.id)])
 
203
            for connection in connection_ids:
 
204
 
 
205
                connection.weight = random.uniform(-1.0, 1.0)
 
206
 
 
207
                connection.error_abs = 0.0
 
208
                connection.error_avg = 0.0
 
209
                connection.error_value = 0.0
 
210
                connection.weight_error = 0.0
 
211
                connection.weight_error_avg = 0.0
 
212
                connection.weight_error_abs = 0.0
 
213
                connection.weight_importance = 10.0
 
214
                connection.error_nb = 1
 
215
                connection.weight_nb = 1
 
216
            neuron_ids = self.env['ann.neuron'].search([('network_id', '=', network.id)])
 
217
            for neuron in neuron_ids:
 
218
                neuron.error_value = 0.0
 
219
                neuron.error_avg = 0.0
 
220
                neuron.error_abs = 0.0
 
221
                neuron.error_nb = 0
 
222
                neuron.value_abs = 0.0
 
223
                neuron.value_avg = 0.0
 
224
                neuron.value_nb = 0.0
 
225
 
 
226
    @api.one
133
227
    def button_train(self):
134
228
        "Train Network"
135
 
        self.button_run()
136
 
 
137
 
        for network in self:
138
 
            layer = network.output_layer_id
139
 
            if network.train_value:
140
 
                train_value = list(reversed(network.train_value.split(' ')))
141
 
                for input_neuron in layer.neuron_ids:
142
 
                    if input_value:
143
 
                        input_neuron.input_value = float(input_value.pop())
144
 
                    else:
145
 
                        input_neuron.input_value = 0.0
146
 
            while layer.next_layer_id:
147
 
                layer.neuron_ids.button_run()
148
 
                layer = layer.next_layer_id
149
 
            output_value = ''
150
 
            layer.neuron_ids.button_run()
151
 
            for output_neuron in layer.neuron_ids:
152
 
                output_value += "%s " % (output_neuron.output_value)
153
 
            network.output_value = output_value
 
229
        for i in range(10):
 
230
            e1 = random.uniform(-10.0, 10.0)
 
231
            e2 = random.uniform(-10.0, 10.0)
 
232
            s1 = -10 * e1 - 5 * e2 + 5
 
233
            s2 = 2
 
234
            self.input_value = "%s %s" % (e1, e2)
 
235
            self.training_value = "%s %s" % (s1, s2)
 
236
 
 
237
            self.button_run()
 
238
            self.button_backforward_error()
 
239
            output1 = self.output_neuron_ids[0].output_value
 
240
            output2 = self.output_neuron_ids[1].output_value
 
241
 
 
242
            if s1 and s2:
 
243
                print abs(int(100.0 * (output1 - s1) / s1)), '\t', abs(int(100.0 * (output2 - s2) / s2))
 
244
 
 
245
 
154
246
 
155
247
    @api.multi
156
248
    def button_create_ann(self):
160
252
            parameters = network.get_parameters()
161
253
            if network.layer_sizes:
162
254
                network.button_init_ann()
163
 
                layer_sizes = network.layer_sizes.split(' ')
 
255
                layer_sizes = network.layer_sizes.strip().split(' ')
 
256
                if len(layer_sizes) < 2:
 
257
                    raise UserError(_("You can't create network without input and output"))
 
258
 
 
259
                layer = False
164
260
                for layer_num_neuron in layer_sizes:
165
261
                    #create layer
166
262
                    layer_vals = {'network_id': network.id}
171
267
                    if layer.previous_layer_id:
172
268
                        layer.previous_layer_id.next_layer_id = layer
173
269
 
174
 
                    activation_function = parameters.get('activation_function', 'threshold')
 
270
                    activation_function = parameters.get('activation_function', 'linear')
175
271
                    if not network.input_layer_id:
176
272
                        network.input_layer_id = layer
177
273
                        activation_function = 'linear'
192
288
                                    'network_id': network.id,
193
289
                                    'to_neuron_id': neuron.id,
194
290
                                    'from_neuron_id': previous_neuron.id,
195
 
                                    'weight': random.uniform(- 1.0, 1.0),
196
291
                                    }
197
292
                                self.env['ann.connection'].create(connection_val)
198
293
 
200
295
                network.output_layer_id = layer
201
296
                for neuron in layer.neuron_ids:
202
297
                    neuron.activation_function = 'linear'
 
298
 
 
299
                network.button_init_weight()
203
300
                network.order_layer()
204
301
 
205
302
    @api.multi
284
381
                                'network_id': network.id,
285
382
                                'to_neuron_id': neuron_ids[int(neuron_configuration_id)],
286
383
                                'from_neuron_id': neuron_ids[int(connection_configuration[connection_configuration_id].split(',')[0].strip())],
287
 
                                'weight': float(connection_configuration[connection_configuration_id].split(',')[1].strip())
 
384
                                'weight_output': float(connection_configuration[connection_configuration_id].split(',')[1].strip())
288
385
                                }
289
386
                                self.env['ann.connection'].create(connection_val)
290
387
                                connection_configuration_id += 1