Adding a weight for each input dimension

This commit is contained in:
emeric
2018-12-09 15:20:29 +01:00
parent 4a06a5a1cf
commit 63abdc782c
3 changed files with 24 additions and 8 deletions
+17 -6
View File
@@ -50,13 +50,16 @@ defaultLearningFactor(Network::Progress progress)
} }
InputVector::value_type InputVector::value_type
euclidianSquareDistance(const InputVector& a, const InputVector& b) euclidianSquareDistance(const InputVector& a, const InputVector& b, const InputVector& weights)
{ {
checkSameDimensions(a, b);
checkSameDimensions(a, weights);
InputVector::value_type res = 0; InputVector::value_type res = 0;
for (std::size_t i = 0; i < a.size(); ++i) for (std::size_t i = 0; i < a.size(); ++i)
{ {
res += (a[i] - b[i]) * (a[i] - b[i]); res += (a[i] - b[i]) * (a[i] - b[i]) * weights[i];
} }
return res; return res;
@@ -159,6 +162,7 @@ Network::Network(std::size_t width, std::size_t height, std::size_t inputDimCoun
: _width(width), : _width(width),
_height(height), _height(height),
_inputDimCount(inputDimCount), _inputDimCount(inputDimCount),
_weights(inputDimCount, static_cast<InputVector::value_type>(1)),
_distanceFunc(euclidianSquareDistance), _distanceFunc(euclidianSquareDistance),
_learningFactorFunc(defaultLearningFactor), _learningFactorFunc(defaultLearningFactor),
_neighborhoodFunc(defaultNeighborhoodFunc) _neighborhoodFunc(defaultNeighborhoodFunc)
@@ -180,6 +184,13 @@ _neighborhoodFunc(defaultNeighborhoodFunc)
} }
} }
void
Network::setDataWeights(const InputVector& weights)
{
checkSameDimensions(weights, _inputDimCount);
_weights = weights;
}
InputVector& InputVector&
Network::getRefVector(std::size_t x, std::size_t y) Network::getRefVector(std::size_t x, std::size_t y)
@@ -217,7 +228,7 @@ Network::getClosestRefVector(const InputVector& data) const
auto it = std::min_element(_refVectors.begin(), _refVectors.end(), auto it = std::min_element(_refVectors.begin(), _refVectors.end(),
[&](const auto& a, const auto& b) [&](const auto& a, const auto& b)
{ {
return (_distanceFunc(a, data) < _distanceFunc(b, data)); return (_distanceFunc(a, data, _weights) < _distanceFunc(b, data, _weights));
}); });
auto index = std::distance(_refVectors.begin(), it); auto index = std::distance(_refVectors.begin(), it);
@@ -271,12 +282,12 @@ Network::train(const std::vector<InputVector>& inputData, std::size_t nbIteratio
inputDataShuffled.push_back(&input); inputDataShuffled.push_back(&input);
} }
std::random_device randomDevice; auto now = std::chrono::system_clock::now();
std::mt19937 generator(randomDevice()); std::mt19937 randGenerator(std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count());
for (std::size_t i = 0; i < nbIterations; ++i) for (std::size_t i = 0; i < nbIterations; ++i)
{ {
std::shuffle(inputDataShuffled.begin(), inputDataShuffled.end(), generator); std::shuffle(inputDataShuffled.begin(), inputDataShuffled.end(), randGenerator);
for (auto input : inputDataShuffled) for (auto input : inputDataShuffled)
{ {
+6 -2
View File
@@ -52,6 +52,9 @@ class Network
Network(std::size_t width, std::size_t height, std::size_t inputDimCount); Network(std::size_t width, std::size_t height, std::size_t inputDimCount);
// Set weight for each dimension (default is 1 for each weight)
void setDataWeights(const InputVector& weights);
// data must be normalized // data must be normalized
void train(const std::vector<InputVector>& dataSamples, std::size_t nbIterations); void train(const std::vector<InputVector>& dataSamples, std::size_t nbIterations);
@@ -64,7 +67,7 @@ class Network
// i is the current iteration // i is the current iteration
// refVector(i+1) = refVector(i) + LearningFactor(i) * NeighborhoodFunc(i) * (MatchingRefVector - refVector) // refVector(i+1) = refVector(i) + LearningFactor(i) * NeighborhoodFunc(i) * (MatchingRefVector - refVector)
using DistanceFunc = std::function<InputVector::value_type(const InputVector&, const InputVector&)>; using DistanceFunc = std::function<InputVector::value_type(const InputVector& /* a */, const InputVector& /* b */, const InputVector& /* weights */)>;
void setDistanceFunc(DistanceFunc distanceFunc); void setDistanceFunc(DistanceFunc distanceFunc);
struct Progress struct Progress
@@ -91,7 +94,8 @@ class Network
std::size_t _height; std::size_t _height;
std::size_t _inputDimCount; std::size_t _inputDimCount;
std::vector<InputVector> _refVectors; // indexed reference vectors InputVector _weights;
std::vector<InputVector> _refVectors; // reference vectors
DistanceFunc _distanceFunc; DistanceFunc _distanceFunc;
LearningFactorFunc _learningFactorFunc; LearningFactorFunc _learningFactorFunc;
+1
View File
@@ -29,6 +29,7 @@ int main(int argc, char *argv[])
{ 80, -1 }, { 80, -1 },
{ 80, -0.75 }, { 80, -0.75 },
{ 240, 0.5 }, { 240, 0.5 },
{ 240, -0.5 },
{ 120, -0.5 }, { 120, -0.5 },
{ 140, -0.5 }, { 140, -0.5 },
}; };