Skip to content

Conversation

@breznak
Copy link
Member

@breznak breznak commented Nov 6, 2019

  • fixes the correctness of creating new synapse on segment
  • moved to Connections, simplified code

as it was never used, use existing Connections.cellForSegment() instead
The logic was moved from TM.growSynapses_() to
Connections.createSynapse() as it's generally applicable and correct.

We want to avoid creating synapses to already existing presynaptic cells
(on the same segment) as that breaks the binary nature of synapses.

Advantage of this is simplified implementation and much cleaner code in
TM.
@breznak breznak self-assigned this Nov 6, 2019
Copy link
Member Author

@breznak breznak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please review below,

//proceed to create a new segment
Segment segment;
if (!destroyedSegments_.empty() ) { //reuse old, destroyed segs
segment = destroyedSegments_.back();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replacing the destroyed_ buffers. Makes code less complicated and the performance is the same.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this will never reuse a destroyed segment?

IMO: in a typical application, segments should never be destroyed, just created. If the HTM reaches full capacity and needs to make room for new information, then the HTM should remove synapses from a segment instead of removing the segment itself.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this will never reuse a destroyed segment?
IMO: in a typical application, segments should never be destroyed, just created.

yes. if you want, I can move this commit to a separete PR to discuss there? You're right we almost never remove segments/synapses (cca 0.X% on hotgym benchmark).

If the HTM reaches full capacity and needs to make room for new information, then the HTM should remove synapses from a segment instead of removing the segment itself.

if that is valid requirement, we should remove altogether the method destroySegment().

HTM reaches full capacity and needs to make room

when is this? When synapses on a segment are full, when synapses on all segments are maxed, ...?

should remove synapses from a segment instead of removing the segment itself.

then we'd need to limit this pruning to some reasonable value (keep more synapses than activation threshold), otherwise the seg can never be active again.

  • currently we do this the other way, that such segment dies off (which I think is more plausible than setting a limit on a number of syns that need be left).

for (const Synapse& syn : synapsesForSegment(segment)) {
const CellIdx existingPresynapticCell = dataForSynapse(syn).presynapticCell; //TODO 1; add way to get all presynaptic cells for segment (fast)
if (presynapticCell == existingPresynapticCell) {
return syn; //synapse (connecting to this presyn cell) already exists on the segment; don't create a new one, exit early and return the existing
Copy link
Member Author

@breznak breznak Nov 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1/ moving code for avoiding duplicate presynaptic connections on the same segment from TM,

  • implementation is easier (&faster about 8% for TM)

2/ was a bug that it was checked only in TM, is applicable generally and should be part of Connections.

* @param cells
* Output array with the same length as 'segments'
*/
void mapSegmentsToCells(const Segment *segments_begin,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed unused method, cellForSegment() provides the same.

Int overrun = static_cast<Int>(connections.numSynapses(segment) + nActual - maxSynapsesPerSegment_);
if (overrun > 0) {
connections.destroyMinPermanenceSynapses(segment, static_cast<Int>(overrun), prevWinnerCells);
connections.destroyMinPermanenceSynapses(segment, static_cast<Int>(overrun), prevWinnerCells); //TODO move this functionality to Connections.createSynapse()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OT: for next PR

connections.createSynapse(segment, 51, 0.34f);
const size_t numSynapses = connections.synapsesForSegment(segment).size(); //created 2 synapses above
connections.createSynapse(segment, 50, 0.48f); //attempt to create already existing synapse (to presyn cell "50") -> skips as no duplication should happen
ASSERT_EQ(connections.synapsesForSegment(segment).size(), numSynapses) << "Duplicit synapses should not be created!";
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test the new "check dupes, skip" behavior of createSynapse.

@breznak breznak added ready bug Something isn't working and removed in_progress labels Nov 6, 2019
Copy link
Collaborator

@ctrl-z-9000-times ctrl-z-9000-times left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that this is a better way to organize the code.

Thank you

//proceed to create a new segment
Segment segment;
if (!destroyedSegments_.empty() ) { //reuse old, destroyed segs
segment = destroyedSegments_.back();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this will never reuse a destroyed segment?

IMO: in a typical application, segments should never be destroyed, just created. If the HTM reaches full capacity and needs to make room for new information, then the HTM should remove synapses from a segment instead of removing the segment itself.

@breznak
Copy link
Member Author

breznak commented Nov 11, 2019

Please re-review when you have time, I have some follow up work on Connections, and I'd like to keep this PR small.

Copy link

@dkeeney dkeeney left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find no problem with this.
@ctrl-z-9000-times should be the one to take a look at this but I will go ahead and approve in case it is holding you up.

Copy link
Collaborator

@ctrl-z-9000-times ctrl-z-9000-times left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have any problems with this, although I have not proof read the code. You should merge this with Mr Keeney's approval.

@breznak
Copy link
Member Author

breznak commented Nov 12, 2019

Thank you both for reviewing, my quite confident this code will be fine 👍
Glad to merge this, it was holding back my research on connections.

@breznak breznak merged commit 686abdf into master Nov 12, 2019
@breznak breznak deleted the connections_createSynapse branch November 12, 2019 15:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request optimization ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants