-
Notifications
You must be signed in to change notification settings - Fork 79
Connections create synapse improvements #746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
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
left a comment
There was a problem hiding this 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(); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
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!"; |
There was a problem hiding this comment.
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.
ctrl-z-9000-times
left a comment
There was a problem hiding this 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(); |
There was a problem hiding this comment.
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.
|
Please re-review when you have time, I have some follow up work on Connections, and I'd like to keep this PR small. |
dkeeney
left a comment
There was a problem hiding this 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.
ctrl-z-9000-times
left a comment
There was a problem hiding this 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.
|
Thank you both for reviewing, my quite confident this code will be fine 👍 |
Uh oh!
There was an error while loading. Please reload this page.