//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// getErrorDerivative //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// RealVector MultiLayerPerceptron::calcErrorAndGradient( const RealVector& input, const RealVector& target, double& error ) { /// The current state on the nodes will be used for backpropagation. error = calcError( input, target ); if ( m_deltaE.size() == 0 ) { /// Calculate the gradient components with a single backward propagation if there are no hidden layers. propagateBackward( m_deltaEOutput, m_deltaEInput, m_weights[ 0 ] ); for ( size_t iInput = 0; iInput < m_weights[ 0 ].size(); ++iInput ) { for ( size_t iOutput = 0; iOutput < m_weights[ 0 ][ iInput ].size(); ++iOutput ) { m_weightDerivatives[ 0 ][ iInput ][ iOutput ] = m_input[ iInput ] * m_deltaEOutput[ iOutput ]; } } } else { /// Calculate the derivatives of the activation function on all the hidden nodes. This is independent of /// backpropagation. calcDerivativesActivationFunc(); /// Propagate output deltas to first hidden node. propagateBackward( m_deltaEOutput, m_deltaE.back(), m_weights.back() ); for ( size_t i = 0; i < m_deltaE.back().size(); ++i ) { m_deltaE.back()[ i ] *= m_dfdy.back()[ i ]; } /// Calculate deltas for all hidden nodes. /// delta_nk = f'(y_nk) * sum_i w_nki delta_(n+1)i /// propageBackward calculates the sum. for ( size_t iHiddenLayer = m_deltaE.size() - 1; iHiddenLayer > 0; --iHiddenLayer ) { propagateBackward( m_deltaE[ iHiddenLayer ], m_deltaE[ iHiddenLayer - 1 ], m_weights[ iHiddenLayer ] ); for ( size_t iNeuron = 0; iNeuron < m_deltaE[ iHiddenLayer - 1 ].size(); ++iNeuron ) { m_deltaE[ iHiddenLayer - 1 ][ iNeuron ] *= m_dfdy[ iHiddenLayer - 1 ][ iNeuron ]; } } /// Calculate the derivatives. dE/dw_nij = x_(n-1)j * delta_i for ( size_t iLayer = 0; iLayer < m_weights.size(); ++iLayer ) { const RealVector& sourceNeuronActivations = iLayer != 0 ? m_x[ iLayer - 1 ] : m_input; const RealVector& deltaVec = iLayer < m_deltaE.size() ? m_deltaE[ iLayer ] : m_deltaEOutput; for ( size_t iSourceNeuron = 0; iSourceNeuron < m_weights[ iLayer ].size(); ++iSourceNeuron ) { for ( size_t iTargetNeuron = 0; iTargetNeuron < m_weights[ iLayer ][ iSourceNeuron ].size(); ++iTargetNeuron ) { m_weightDerivatives[ iLayer ][ iSourceNeuron ][ iTargetNeuron ] = sourceNeuronActivations[ iSourceNeuron ] * deltaVec[ iTargetNeuron ]; } } } } /// @see composeGradient return composeGradient(); }
bool run() { #if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE) m_count = 0; #endif // 1) propagate predictions do { m_changed = false; // Forward propagation is near-optimal for both topologically-sorted and // DFS-sorted code. propagateForward(); if (!m_changed) break; // Backward propagation reduces the likelihood that pathological code will // cause slowness. Loops (especially nested ones) resemble backward flow. // This pass captures two cases: (1) it detects if the forward fixpoint // found a sound solution and (2) short-circuits backward flow. m_changed = false; propagateBackward(); } while (m_changed); // 2) repropagate predictions while doing double voting. do { m_changed = false; doRoundOfDoubleVoting(); propagateForward(); if (!m_changed) break; m_changed = false; doRoundOfDoubleVoting(); propagateBackward(); } while (m_changed); return true; }
bool FirmwareMaster::handleMessage(Message &message) { int remaining; byte slavesCount; uint16_t temp; DateTime now; bool s; uint32_t pcId; switch (message.m_type) { case SCAN_MESSAGE_RESPONSE: d.println(F("SCAN_MESSAGE_RESPONSE:")); s = m_bank_data.registerId(message.m_fromId); break; case SCAN_MESSAGE_START: d.println(F("SCAN_MESSAGE_START:")); pcId = message.m_fromId; message.clearData(); set(message, m_id, 0, SCAN_MESSAGE); propagateForward(message); message.m_targetId = pcId; message.m_type = SCAN_MESSAGE_START_RESPONSE; return true; case MASTER_DATA_READ: d.println(F("MASTER_DATA_READ:")); Utils::toByte(temp = (uint16_t)m_temp_sensor.readDigital(), message.m_data); d.print(F("t=")).println(temp); Utils::toByte(temp = (uint16_t)m_current_sensor.read(), message.m_data+2); d.print(F("i=")).println(temp); Utils::toByte(temp = (uint16_t)m_voltage_sensor.read(), message.m_data+4); d.print(F("v=")).println(temp); set(message, m_id, message.m_fromId, MASTER_DATA_READ_RESPONSE); return true; case MASTER_DATA_GATHER: d.println(F("MASTER_DATA_GATHER:")); now = m_rtc_clock.now(); m_bank_data.setTime(now.year(), now.month(), now.day(), now.hour(), now.minute(), now.second()); remaining = m_bank_data.addData( m_id, m_temp_sensor.readDigital(), m_current_sensor.read(), m_voltage_sensor.read() ); // Do not emit a response until all data is gathered first! if (remaining > 0) { // this handles the case when no slave are connected to master d.print(F("Emitting SLAVE_DATA_READ command to")); // Emit one SLAVE_DATA_READ message to every connected slave set(message, m_id, 0, SLAVE_DATA_READ); message.clearData(); slavesCount = m_bank_data.registeredIdCount(); d.print((uint32_t)slavesCount).println(" slaves"); for (byte i = 0; i < slavesCount; i++) { message.m_targetId = m_bank_data.registeredIdAt(i); propagateForward(message); } } else { set(message, m_id, message.m_fromId, MASTER_DATA_GATHER_RESPONSE); message.clearData(); message.m_data[CUSTOM_MESSAGE_DATA_LENGTH-1] = 1; return true; } break; case SLAVE_DATA_READ_RESPONSE: d.println(F("SLAVE_DATA_READ_RESPONSE:")); // When the last requested SLAVE_DATA_READ response is processed, the file will be // automatically flushed to a new csv row. remaining = m_bank_data.addData( message.m_fromId, message.m_data ); if (remaining == 0) { set(message, m_id, 1234, MASTER_DATA_GATHER_COMPLETE); message.clearData(); message.m_data[CUSTOM_MESSAGE_DATA_LENGTH-1] = 1; propagateBackward(message); return false; } break; case MASTER_ID_WRITE: d.println(F("MASTER_ID_WRITE")); m_eeprom_writer.writeId(Utils::toInt32(message.m_data)); message.clearData(); message.m_data[CUSTOM_MESSAGE_DATA_LENGTH-1] = 1; message.m_type = MASTER_ID_WRITE_RESPONSE; message.m_targetId = message.m_fromId; message.m_fromId = m_id; return true; case MASTER_GPS_TIME_GET: case MASTER_GPS_DATE_GET: case MASTER_GPS_LAT_GET: case MASTER_GPS_LON_GET: case MASTER_GPS_ALTITUDE_GET: case MASTER_GPS_FIX_TYPE_GET: case MASTER_GPS_SPEED_GET: case MASTER_GPS_TRACK_GET: case MASTER_GPS_QUALITY_GET: //case MASTER_GPS_ENABLED_GET: // TODO: finish this command return processGpsCommand(message); } return false; }