////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 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();
}
Esempio n. 2
0
    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;
    }
Esempio n. 3
0
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;
}