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
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;
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;
@@ -159,6 +162,7 @@ Network::Network(std::size_t width, std::size_t height, std::size_t inputDimCoun
: _width(width),
_height(height),
_inputDimCount(inputDimCount),
_weights(inputDimCount, static_cast<InputVector::value_type>(1)),
_distanceFunc(euclidianSquareDistance),
_learningFactorFunc(defaultLearningFactor),
_neighborhoodFunc(defaultNeighborhoodFunc)
@@ -180,6 +184,13 @@ _neighborhoodFunc(defaultNeighborhoodFunc)
}
}
void
Network::setDataWeights(const InputVector& weights)
{
checkSameDimensions(weights, _inputDimCount);
_weights = weights;
}
InputVector&
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(),
[&](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);
@@ -271,12 +282,12 @@ Network::train(const std::vector<InputVector>& inputData, std::size_t nbIteratio
inputDataShuffled.push_back(&input);
}
std::random_device randomDevice;
std::mt19937 generator(randomDevice());
auto now = std::chrono::system_clock::now();
std::mt19937 randGenerator(std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count());
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)
{
+6 -2
View File
@@ -52,6 +52,9 @@ class Network
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
void train(const std::vector<InputVector>& dataSamples, std::size_t nbIterations);
@@ -64,7 +67,7 @@ class Network
// i is the current iteration
// 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);
struct Progress
@@ -91,7 +94,8 @@ class Network
std::size_t _height;
std::size_t _inputDimCount;
std::vector<InputVector> _refVectors; // indexed reference vectors
InputVector _weights;
std::vector<InputVector> _refVectors; // reference vectors
DistanceFunc _distanceFunc;
LearningFactorFunc _learningFactorFunc;