/**
|
* @license
|
* Copyright 2023 CodeSmith LLC
|
*
|
* Use of this source code is governed by an MIT-style
|
* license that can be found in the LICENSE file or at
|
* https://opensource.org/licenses/MIT.
|
* =============================================================================
|
*/
|
import { image, serialization, tidy } from '@tensorflow/tfjs-core';
|
import { getExactlyOneTensor, getExactlyOneShape } from '../../utils/types_utils';
|
import { ValueError } from '../../errors';
|
import { BaseRandomLayer } from '../../engine/base_random_layer';
|
import { randomUniform } from '@tensorflow/tfjs-core';
|
const INTERPOLATION_KEYS = ['bilinear', 'nearest'];
|
export const INTERPOLATION_METHODS = new Set(INTERPOLATION_KEYS);
|
/**
|
* Preprocessing Layer with randomly varies image during training
|
*
|
* This layer randomly adjusts the height of a
|
* batch of images by a random factor.
|
*
|
* The input should be a 3D (unbatched) or
|
* 4D (batched) tensor in the `"channels_last"` image data format. Input pixel
|
* values can be of any range (e.g. `[0., 1.)` or `[0, 255]`) and of interger
|
* or floating point dtype. By default, the layer will output floats.
|
*
|
* tf methods implemented in tfjs: 'bilinear', 'nearest',
|
* tf methods unimplemented in tfjs: 'bicubic', 'area', 'lanczos3', 'lanczos5',
|
* 'gaussian', 'mitchellcubic'
|
*
|
*/
|
class RandomHeight extends BaseRandomLayer {
|
constructor(args) {
|
super(args);
|
const { factor, interpolation = 'bilinear' } = args;
|
this.factor = factor;
|
if (Array.isArray(this.factor) && this.factor.length === 2) {
|
this.heightLower = this.factor[0];
|
this.heightUpper = this.factor[1];
|
}
|
else if (!Array.isArray(this.factor) && this.factor > 0) {
|
this.heightLower = -this.factor;
|
this.heightUpper = this.factor;
|
}
|
else {
|
throw new ValueError(`Invalid factor: ${this.factor}. Must be positive number or tuple of 2 numbers`);
|
}
|
if (this.heightLower < -1.0 || this.heightUpper < -1.0) {
|
throw new ValueError(`factor must have values larger than -1. Got: ${this.factor}`);
|
}
|
if (this.heightUpper < this.heightLower) {
|
throw new ValueError(`factor cannot have upper bound less than lower bound.
|
Got upper bound: ${this.heightUpper}.
|
Got lower bound: ${this.heightLower}
|
`);
|
}
|
if (interpolation) {
|
if (INTERPOLATION_METHODS.has(interpolation)) {
|
this.interpolation = interpolation;
|
}
|
else {
|
throw new ValueError(`Invalid interpolation parameter: ${interpolation} is not implemented`);
|
}
|
}
|
}
|
getConfig() {
|
const config = {
|
'factor': this.factor,
|
'interpolation': this.interpolation,
|
};
|
const baseConfig = super.getConfig();
|
Object.assign(config, baseConfig);
|
return config;
|
}
|
computeOutputShape(inputShape) {
|
inputShape = getExactlyOneShape(inputShape);
|
const numChannels = inputShape[2];
|
return [-1, this.imgWidth, numChannels];
|
}
|
call(inputs, kwargs) {
|
return tidy(() => {
|
const input = getExactlyOneTensor(inputs);
|
this.imgWidth = input.shape[input.shape.length - 2];
|
const imgHeight = input.shape[input.shape.length - 3];
|
this.heightFactor = randomUniform([1], (1.0 + this.heightLower), (1.0 + this.heightUpper), 'float32', this.randomGenerator.next());
|
let adjustedHeight = this.heightFactor.dataSync()[0] * imgHeight;
|
adjustedHeight = Math.round(adjustedHeight);
|
const size = [adjustedHeight, this.imgWidth];
|
switch (this.interpolation) {
|
case 'bilinear':
|
return image.resizeBilinear(inputs, size);
|
case 'nearest':
|
return image.resizeNearestNeighbor(inputs, size);
|
default:
|
throw new Error(`Interpolation is ${this.interpolation}
|
but only ${[...INTERPOLATION_METHODS]} are supported`);
|
}
|
});
|
}
|
}
|
/** @nocollapse */
|
RandomHeight.className = 'RandomHeight';
|
export { RandomHeight };
|
serialization.registerClass(RandomHeight);
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFuZG9tX2hlaWdodC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3RmanMtbGF5ZXJzL3NyYy9sYXllcnMvcHJlcHJvY2Vzc2luZy9yYW5kb21faGVpZ2h0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBRUgsT0FBTyxFQUFFLEtBQUssRUFBUSxhQUFhLEVBQVUsSUFBSSxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDakYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHbEYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUMxQyxPQUFPLEVBQXVCLGVBQWUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVN0RCxNQUFNLGtCQUFrQixHQUFHLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBVSxDQUFDO0FBQzVELE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLElBQUksR0FBRyxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFHakU7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsTUFBYSxZQUFhLFNBQVEsZUFBZTtJQVUvQyxZQUFZLElBQXNCO1FBQ2hDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNaLE1BQU0sRUFBQyxNQUFNLEVBQUUsYUFBYSxHQUFHLFVBQVUsRUFBQyxHQUFHLElBQUksQ0FBQztRQUVsRCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUVyQixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUMxRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7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Q2pFLGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBRTVDLE1BQU0sSUFBSSxHQUFvQixDQUFDLGNBQWMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFFOUQsUUFBUSxJQUFJLENBQUMsYUFBYSxFQUFFO2dCQUMxQixLQUFLLFVBQVU7b0JBQ2IsT0FBTyxLQUFLLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDNUMsS0FBSyxTQUFTO29CQUNaLE9BQU8sS0FBSyxDQUFDLHFCQUFxQixDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDbkQ7b0JBQ0UsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsSUFBSSxDQUFDLGFBQWE7cUJBQzNDLENBQUMsR0FBRyxxQkFBcUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2FBQzFEO1FBQ0gsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDOztBQS9GRCxrQkFBa0I7QUFDRixzQkFBUyxHQUFHLGNBQWMsQ0FBQztTQUZoQyxZQUFZO0FBbUd6QixhQUFhLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMjMgQ29kZVNtaXRoIExMQ1xuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZVxuICogbGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIG9yIGF0XG4gKiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVC5cbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKi9cblxuaW1wb3J0IHsgaW1hZ2UsIFJhbmssIHNlcmlhbGl6YXRpb24sIFRlbnNvciwgdGlkeSB9IGZyb20gJ0B0ZW5zb3JmbG93L3RmanMtY29yZSc7XG5pbXBvcnQgeyBnZXRFeGFjdGx5T25lVGVuc29yLCBnZXRFeGFjdGx5T25lU2hhcGUgfSBmcm9tICcuLi8uLi91dGlscy90eXBlc191dGlscyc7XG5pbXBvcnQgeyBTaGFwZSB9IGZyb20gJy4uLy4uL2tlcmFzX2Zvcm1hdC9jb21tb24nO1xuaW1wb3J0IHsgS3dhcmdzIH0gZnJvbSAnLi4vLi4vdHlwZXMnO1xuaW1wb3J0IHsgVmFsdWVFcnJvciB9IGZyb20gJy4uLy4uL2Vycm9ycyc7XG5pbXBvcnQgeyBCYXNlUmFuZG9tTGF5ZXJBcmdzLCBCYXNlUmFuZG9tTGF5ZXIgfSBmcm9tICcuLi8uLi9lbmdpbmUvYmFzZV9yYW5kb21fbGF5ZXInO1xuaW1wb3J0IHsgcmFuZG9tVW5pZm9ybSB9IGZyb20gJ0B0ZW5zb3JmbG93L3RmanMtY29yZSc7XG5cbmV4cG9ydCBkZWNsYXJlIGludGVyZmFjZSBSYW5kb21IZWlnaHRBcmdzIGV4dGVuZHMgQmFzZVJhbmRvbUxheWVyQXJncyB7XG4gICBmYWN0b3I6IG51bWJlciB8IFtudW1iZXIsIG51bWJlcl07XG4gICBpbnRlcnBvbGF0aW9uPzogSW50ZXJwb2xhdGlvblR5cGU7IC8vIGRlZmF1bHQgPSAnYmlsaW5lYXInO1xuICAgc2VlZD86IG51bWJlcjsgLy8gZGVmYXVsdCA9IG51bGw7XG4gICBhdXRvVmVjdG9yaXplPzogYm9vbGVhbjtcbn1cblxuY29uc3QgSU5URVJQT0xBVElPTl9LRVlTID0gWydiaWxpbmVhcicsICduZWFyZXN0J10gYXMgY29uc3Q7XG5leHBvcnQgY29uc3QgSU5URVJQT0xBVElPTl9NRVRIT0RTID0gbmV3IFNldChJTlRFUlBPTEFUSU9OX0tFWVMpO1xudHlwZSBJbnRlcnBvbGF0aW9uVHlwZSA9IHR5cGVvZiBJTlRFUlBPTEFUSU9OX0tFWVNbbnVtYmVyXTtcblxuLyoqXG4gKiBQcmVwcm9jZXNzaW5nIExheWVyIHdpdGggcmFuZG9tbHkgdmFyaWVzIGltYWdlIGR1cmluZyB0cmFpbmluZ1xuICpcbiAqIFRoaXMgbGF5ZXIgcmFuZG9tbHkgYWRqdXN0cyB0aGUgaGVpZ2h0IG9mIGFcbiAqIGJhdGNoIG9mIGltYWdlcyBieSBhIHJhbmRvbSBmYWN0b3IuXG4gKlxuICogVGhlIGlucHV0IHNob3VsZCBiZSBhIDNEICh1bmJhdGNoZWQpIG9yXG4gKiA0RCAoYmF0Y2hlZCkgdGVuc29yIGluIHRoZSBgXCJjaGFubmVsc19sYXN0XCJgIGltYWdlIGRhdGEgZm9ybWF0LiBJbnB1dCBwaXhlbFxuICogdmFsdWVzIGNhbiBiZSBvZiBhbnkgcmFuZ2UgKGUuZy4gYFswLiwgMS4pYCBvciBgWzAsIDI1NV1gKSBhbmQgb2YgaW50ZXJnZXJcbiAqIG9yIGZsb2F0aW5nIHBvaW50IGR0eXBlLiBCeSBkZWZhdWx0LCB0aGUgbGF5ZXIgd2lsbCBvdXRwdXQgZmxvYXRzLlxuICpcbiAqIHRmIG1ldGhvZHMgaW1wbGVtZW50ZWQgaW4gdGZqczogJ2JpbGluZWFyJywgJ25lYXJlc3QnLFxuICogdGYgbWV0aG9kcyB1bmltcGxlbWVudGVkIGluIHRmanM6ICdiaWN1YmljJywgJ2FyZWEnLCAnbGFuY3pvczMnLCAnbGFuY3pvczUnLFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdnYXVzc2lhbicsICdtaXRjaGVsbGN1YmljJ1xuICpcbiAqL1xuXG5leHBvcnQgY2xhc3MgUmFuZG9tSGVpZ2h0IGV4dGVuZHMgQmFzZVJhbmRvbUxheWVyIHtcbiAgLyoqIEBub2NvbGxhcHNlICovXG4gIHN0YXRpYyBvdmVycmlkZSBjbGFzc05hbWUgPSAnUmFuZG9tSGVpZ2h0JztcbiAgcHJpdmF0ZSByZWFkb25seSBmYWN0b3I6IG51bWJlciB8IFtudW1iZXIsIG51bWJlcl07XG4gIHByaXZhdGUgcmVhZG9ubHkgaW50ZXJwb2xhdGlvbj86IEludGVycG9sYXRpb25UeXBlOyAgLy8gZGVmdWFsdCA9ICdiaWxpbmVhclxuICBwcml2YXRlIGhlaWdodExvd2VyOiBudW1iZXI7XG4gIHByaXZhdGUgaGVpZ2h0VXBwZXI6IG51bWJlcjtcbiAgcHJpdmF0ZSBpbWdXaWR0aDogbnVtYmVyO1xuICBwcml2YXRlIGhlaWdodEZhY3RvcjogVGVuc29yPFJhbmsuUjE+O1xuXG4gIGNvbnN0cnVjdG9yKGFyZ3M6IFJhbmRvbUhlaWdodEFyZ3MpIHtcbiAgICBzdXBlcihhcmdzKTtcbiAgICBjb25zdCB7ZmFjdG9yLCBpbnRlcnBvbGF0aW9uID0gJ2JpbGluZWFyJ30gPSBhcmdzO1xuXG4gICAgdGhpcy5mYWN0b3IgPSBmYWN0b3I7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheSh0aGlzLmZhY3RvcikgJiYgdGhpcy5mYWN0b3IubGVuZ3RoID09PSAyKSB7XG4gICAgICB0aGlzLmhlaWdodExvd2VyID0gdGhpcy5mYWN0b3JbMF07XG4gICAgICB0aGlzLmhlaWdodFVwcGVyID0gdGhpcy5mYWN0b3JbMV07XG4gICAgfSBlbHNlIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLmZhY3RvcikgJiYgdGhpcy5mYWN0b3IgPiAwKXtcbiAgICAgIHRoaXMuaGVpZ2h0TG93ZXIgPSAtdGhpcy5mYWN0b3I7XG4gICAgICB0aGlzLmhlaWdodFVwcGVyID0gdGhpcy5mYWN0b3I7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBWYWx1ZUVycm9yKFxuICAgICAgICBgSW52YWxpZCBmYWN0b3I6ICR7dGhpcy5mYWN0b3J9LiBNdXN0IGJlIHBvc2l0aXZlIG51bWJlciBvciB0dXBsZSBvZiAyIG51bWJlcnNgXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAodGhpcy5oZWlnaHRMb3dlciA8IC0xLjAgfHwgdGhpcy5oZWlnaHRVcHBlciA8IC0xLjApIHtcbiAgICAgIHRocm93IG5ldyBWYWx1ZUVycm9yKFxuICAgICAgICBgZmFjdG9yIG11c3QgaGF2ZSB2YWx1ZXMgbGFyZ2VyIHRoYW4gLTEuIEdvdDogJHt0aGlzLmZhY3Rvcn1gXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmhlaWdodFVwcGVyIDwgdGhpcy5oZWlnaHRMb3dlcikge1xuICAgICAgdGhyb3cgbmV3IFZhbHVlRXJyb3IoXG4gICAgICAgIGBmYWN0b3IgY2Fubm90IGhhdmUgdXBwZXIgYm91bmQgbGVzcyB0aGFuIGxvd2VyIGJvdW5kLlxuICAgICAgICBHb3QgdXBwZXIgYm91bmQ6ICR7dGhpcy5oZWlnaHRVcHBlcn0uXG4gICAgICAgIEdvdCBsb3dlciBib3VuZDogJHt0aGlzLmhlaWdodExvd2VyfVxuICAgICAgYCk7XG4gICAgfVxuXG4gICAgaWYgKGludGVycG9sYXRpb24pIHtcbiAgICAgIGlmIChJTlRFUlBPTEFUSU9OX01FVEhPRFMuaGFzKGludGVycG9sYXRpb24pKSB7XG4gICAgICAgIHRoaXMuaW50ZXJwb2xhdGlvbiA9IGludGVycG9sYXRpb247XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgVmFsdWVFcnJvcihgSW52YWxpZCBpbnRlcnBvbGF0aW9uIHBhcmFtZXRlcjogJHtcbiAgICAgICAgICAgIGludGVycG9sYXRpb259IGlzIG5vdCBpbXBsZW1lbnRlZGApO1xuICAgICAgfVxuICAgIH0gXG4gIH1cblxuICBvdmVycmlkZSBnZXRDb25maWcoKTogc2VyaWFsaXphdGlvbi5Db25maWdEaWN0IHtcbiAgICBjb25zdCBjb25maWc6IHNlcmlhbGl6YXRpb24uQ29uZmlnRGljdCA9IHtcbiAgICAgICdmYWN0b3InOiB0aGlzLmZhY3RvcixcbiAgICAgICdpbnRlcnBvbGF0aW9uJzogdGhpcy5pbnRlcnBvbGF0aW9uLFxuICAgIH07XG5cbiAgICBjb25zdCBiYXNlQ29uZmlnID0gc3VwZXIuZ2V0Q29uZmlnKCk7XG4gICAgT2JqZWN0LmFzc2lnbihjb25maWcsIGJhc2VDb25maWcpO1xuICAgIHJldHVybiBjb25maWc7XG4gIH1cblxuICBvdmVycmlkZSBjb21wdXRlT3V0cHV0U2hhcGUoaW5wdXRTaGFwZTogU2hhcGV8U2hhcGVbXSk6IFNoYXBlfFNoYXBlW10ge1xuICAgIGlucHV0U2hhcGUgPSBnZXRFeGFjdGx5T25lU2hhcGUoaW5wdXRTaGFwZSk7XG4gICAgY29uc3QgbnVtQ2hhbm5lbHMgPSBpbnB1dFNoYXBlWzJdO1xuICAgIHJldHVybiBbLTEsIHRoaXMuaW1nV2lkdGgsIG51bUNoYW5uZWxzXTtcbiAgfVxuXG4gIG92ZXJyaWRlIGNhbGwoaW5wdXRzOiBUZW5zb3I8UmFuay5SMz58VGVuc29yPFJhbmsuUjQ+LFxuICAgIGt3YXJnczogS3dhcmdzKTogVGVuc29yW118VGVuc29yIHtcblxuICAgIHJldHVybiB0aWR5KCgpID0+IHtcbiAgICAgIGNvbnN0IGlucHV0ID0gZ2V0RXhhY3RseU9uZVRlbnNvcihpbnB1dHMpO1xuICAgICAgdGhpcy5pbWdXaWR0aCA9IGlucHV0LnNoYXBlW2lucHV0LnNoYXBlLmxlbmd0aCAtIDJdO1xuICAgICAgY29uc3QgaW1nSGVpZ2h0ID0gaW5wdXQuc2hhcGVbaW5wdXQuc2hhcGUubGVuZ3RoIC0gM107XG5cbiAgICAgIHRoaXMuaGVpZ2h0RmFjdG9yID0gcmFuZG9tVW5pZm9ybShbMV0sXG4gICAgICAgICgxLjAgKyB0aGlzLmhlaWdodExvd2VyKSwgKDEuMCArIHRoaXMuaGVpZ2h0VXBwZXIpLFxuICAgICAgICAnZmxvYXQzMicsIHRoaXMucmFuZG9tR2VuZXJhdG9yLm5leHQoKVxuICAgICAgKTtcblxuICAgICAgbGV0IGFkanVzdGVkSGVpZ2h0ID0gdGhpcy5oZWlnaHRGYWN0b3IuZGF0YVN5bmMoKVswXSAqIGltZ0hlaWdodDtcbiAgICAgIGFkanVzdGVkSGVpZ2h0ID0gTWF0aC5yb3VuZChhZGp1c3RlZEhlaWdodCk7XG5cbiAgICAgIGNvbnN0IHNpemU6W251bWJlciwgbnVtYmVyXSA9IFthZGp1c3RlZEhlaWdodCwgdGhpcy5pbWdXaWR0aF07XG5cbiAgICAgIHN3aXRjaCAodGhpcy5pbnRlcnBvbGF0aW9uKSB7XG4gICAgICAgIGNhc2UgJ2JpbGluZWFyJzpcbiAgICAgICAgICByZXR1cm4gaW1hZ2UucmVzaXplQmlsaW5lYXIoaW5wdXRzLCBzaXplKTtcbiAgICAgICAgY2FzZSAnbmVhcmVzdCc6XG4gICAgICAgICAgcmV0dXJuIGltYWdlLnJlc2l6ZU5lYXJlc3ROZWlnaGJvcihpbnB1dHMsIHNpemUpO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW50ZXJwb2xhdGlvbiBpcyAke3RoaXMuaW50ZXJwb2xhdGlvbn1cbiAgICAgICAgICBidXQgb25seSAke1suLi5JTlRFUlBPTEFUSU9OX01FVEhPRFNdfSBhcmUgc3VwcG9ydGVkYCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuc2VyaWFsaXphdGlvbi5yZWdpc3RlckNsYXNzKFJhbmRvbUhlaWdodCk7XG4iXX0=
|