1!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{};e._sentryModuleMetadata=e._sentryModuleMetadata||{},e._sentryModuleMetadata[(new e.Error).stack]=function(e){for(var t=1;t<arguments.length;t++){var s=arguments[t];if(null!=s)for(var i in s)s.hasOwnProperty(i)&&(e[i]=s[i])}return e}({},e._sentryModuleMetadata[(new e.Error).stack],{"_sentryBundlerPluginAppKey:kombo-app":!0})}catch(e){}}();"use strict";(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[6640],{4220:(e,t,s)=>{s.d(t,{Gw:()=>N});var i=s(47740),n=s(88852),l=s(46569),r=s(4222),a=s(98112),o=s(77086),h=s(35656),u=s(67055),p=s(11824),c=s(96991),f=s(4858),d=s(69140),g=s(59300),m=s(20725),y=s(9933),w=s(65385),b=s(29397),T=s(48124),v=s(74071),$=s(48057),O=s(60258);function E(e){return Array.isArray(e)}function A(e){return!(e instanceof i.qYS)&&!E(e)}function z(e,t,s,i=!0,n=""){let l;if(null==t||0===t.length){if(null!=e){let t=!1;if(E(e)&&e.length>0)t=!0;else if(A(e)){for(let s in e)if(e.hasOwnProperty(s)){t=!0;break}}else t=!0;if(t)throw new a.Qp(`Error when checking model ${n} expected no data, but got ${e}`)}return[]}if(null==e)return t.map(e=>null);if(A(e))for(let s of(l=[],t)){if(null==e[s])throw new a.Qp(`No data provided for "${s}". Need data for each key in: ${t}`);l.push(e[s])}else if(E(e)){if(e.length!==t.length)throw new a.Qp(`Error when checking model ${n}: the Array of Tensors that you are passing to your model is not the size the model expected. Expected to see ${t.length} Tensor(s), but instead got the following list of Tensor(s): ${e}`);l=e}else{if(t.length>1)throw new a.Qp(`The model ${n} expects ${t.length} Tensor(s), but only received one Tensor. Found: Tensor with shape ${e.shape}`);l=[e]}if(l=(0,$.n4)(l),null!=s)for(let e=0;e<t.length;++e){if(null==s[e])continue;let r=l[e];if(r.shape.length!==s[e].length)throw new a.Qp(`Error when checking ${n}: expected ${t[e]} to have ${s[e].length} dimension(s). but got array with shape ${r.shape}`);for(let t=0;t<s[e].length;++t){if(0===t&&!i)continue;let l=r.shape[t],o=s[e][t];if(null!=o&&o>=0&&l!==o)throw new a.Qp(`${n} expected a batch of elements where each example has shape [${s[e].slice(1,s[e].length)}] (i.e.,tensor shape [*,${s[e].slice(1,s[e].length)}]) but the ${n} received an input with ${r.shape[0]} examples, each with shape [${r.shape.slice(1,r.shape.length)}] (tensor shape [${r.shape}])`)}}return l}function S(e,t,s,i=!0,n=""){let l;if(Array.isArray(e)){if(e.length!==t.length)throw new a.Qp(`Error when checking model ${n}: the Array of Tensors that you are passing to your model is not the size the the model expected. Expected to see ${t.length} Tensor(s), but instead got ${e.length} Tensors(s).`);l=e}else{if(t.length>1)throw new a.Qp(`The model expects ${t.length} ${n} Tensors, but only received one Tensor. Found: array with shape ${JSON.stringify(e.shape)}.`);l=[e]}if(null!=s)for(let e=0;e<t.length;++e){if(null==s[e])continue;let r=l[e];if(r.shape.length!==s[e].length)throw new a.Qp(`Error when checking ${n}: expected ${t[e]} to have ${s[e].length} dimension(s), but got array with shape ${JSON.stringify(r.shape)}`);for(let l=0;l<s[e].length;++l){if(0===l&&!i)continue;let o=r.shape[l],h=s[e][l];if(null!=h&&h!==o)throw new a.Qp(`Error when checking ${n}: expected ${t[e]} to have shape ${JSON.stringify(s[e])} but got array with shape ${JSON.stringify(r.shape)}.`)}}}class N extends b.m{constructor(e){super(e),this.isTraining=!1}summary(e,t,s=console.log){if(!this.built)throw new a.Qp("This model has never been called, thus its weights have not been created yet. So no summary can be displayed. Build the model first (e.g., by calling it on some test data).");(0,g.o)(this,e,t,s)}compile(e){if(null==e.loss&&(e.loss=[]),this.loss=e.loss,"string"==typeof e.optimizer)this.optimizer_=c.K(e.optimizer),this.isOptimizerOwned=!0;else{if(!(e.optimizer instanceof i.ELo))throw new a.Qp("User-defined optimizer must be an instance of tf.Optimizer.");this.optimizer_=e.optimizer,this.isOptimizerOwned=!1}let t=[];if(Array.isArray(e.loss)||"string"==typeof e.loss||"function"==typeof e.loss)if(Array.isArray(e.loss)){if(e.loss.length!==this.outputs.length)throw new a.Qp(`When passing an Array as loss, it should have one entry per model output. The model has ${this.outputs.length} output(s), but you passed loss=${e.loss}.`);t=e.loss.map(e=>u.Jt(e))}else{let s=u.Jt(e.loss);
1this.outputs.forEach(e=>{t.push(s)})}else{for(let t in e.loss=e.loss,e.loss)if(-1===this.outputNames.indexOf(t))throw new a.Qp(`Unknown entry in loss dictionary: "${t}". Only expected the following keys: ${this.outputNames}`);for(let s of this.outputNames)null==e.loss[s]&&console.warn(`Output "${s}" is missing from loss dictionary. We assume this was done on purpose, and we will not be expecting data to be passed to ${s} during training`),t.push(u.Jt(e.loss[s]))}this.lossFunctions=t,this.feedOutputNames=[],this.feedOutputShapes=[],this.feedLossFns=[];for(let e=0;e<this.outputs.length;++e){let t=this.internalOutputShapes[e],s=this.outputNames[e];this.feedOutputNames.push(s),this.feedOutputShapes.push(t),this.feedLossFns.push(this.lossFunctions[e])}let s=[];this.metrics=e.metrics,this.metricsNames=["loss"],this.metricsTensors=[],(0,r.IU)("loss",()=>{for(let e=0;e<this.outputs.length;++e){if(-1!==s.indexOf(e))continue;let t=this.lossFunctions[e];this.outputs.length>1&&(this.metricsTensors.push([t,e]),this.metricsNames.push(this.outputNames[e]+"_loss"))}});let n=function(e,t){let s;if(null==e||Array.isArray(e)&&0===e.length)return t.map(e=>[]);if("string"==typeof e||"function"==typeof e)s=[e];else if(Array.isArray(e)||"object"==typeof e)s=e;else throw TypeError(`Type of metrics argument not understood. Expected an string,function, Array, or Object, found: ${e}`);if(Array.isArray(s))return t.map(e=>s);{let e=[];for(let i of t){let t=s.hasOwnProperty(i)?s[i]:[];Array.isArray(t)||(t=[t]),e.push(t)}return e}}(e.metrics,this.outputNames),l=(e,t,s)=>{this.outputNames.length>1&&(t=this.outputNames[e]+"_"+t),this.metricsNames.push(t),this.metricsTensors.push([s,e])};(0,r.IU)("metric",()=>{for(let e=0;e<this.outputs.length;++e){if(-1===s.indexOf(e))(t=>{let s,i,n;for(let a of t){let t;if("string"==typeof a&&-1!==["accuracy","acc","crossentropy","ce"].indexOf(a)){let t,l=this.internalOutputShapes[e];1===l[l.length-1]||this.lossFunctions[e]===u.Jc?-1!==["accuracy","acc"].indexOf(a)?i=p.xM:-1!==["crossentropy","ce"].indexOf(a)&&(i=p.Jc):this.lossFunctions[e]===u.qp?-1!==["accuracy","acc"].indexOf(a)?i=p.qv:-1!==["crossentropy","ce"].indexOf(a)&&(i=p.qp):-1!==["accuracy","acc"].indexOf(a)?i=p.yP:-1!==["crossentropy","ce"].indexOf(a)&&(i=p.Ol),-1!==["accuracy","acc"].indexOf(a)?t="acc":-1!==["crossentropy","ce"].indexOf(a)&&(t="ce"),n=i,s=""+t}else n=p.Jt(a),s=""+p.GT(a);(0,r.IU)(s,()=>{t=n}),l(e,s,t)}})(n[e])}}),this.collectedTrainableWeights=this.trainableWeights}checkTrainableWeightsConsistency(){null!=this.collectedTrainableWeights&&this.trainableWeights.length!==this.collectedTrainableWeights.length&&console.warn("Discrepancy between trainableweights and collected trainable weights. Did you set `model.trainable` without calling `model.compile()` afterwards?")}evaluate(e,t,s={}){let i=null==s.batchSize?32:s.batchSize;(0,$.yy)(i);let n=this.standardizeUserDataXY(e,t,!0,i);try{let e=n[0].concat(n[1]);this.makeTestFunction();let t=this.testFunction,l=this.testLoop(t,e,i,s.verbose,s.steps);return(0,d.wL)(l)}finally{(0,$.Ec)(n[0],e),(0,$.Ec)(n[1],t)}}async evaluateDataset(e,t){return this.makeTestFunction(),(0,v.c)(this,e,t)}checkNumSamples(e,t,s,i="steps"){let n;if(null!=s){if(n=null,null!=t)throw new a.Qp(`If ${i} is set, batchSize must be null or undefined.Got batchSize = ${t}`)}else if(null!=e)n=Array.isArray(e)?e[0].shape[0]:e.shape[0];else throw new a.Qp(`Either the input data should have a defined shape, or ${i} shoud be specified.`);return n}execute(e,t){if(Array.isArray(t)&&0===t.length)throw new a.Qp("`outputs` is an empty Array, which is not allowed.");let s=Array.isArray(t),n=s?t:[t],l=this.retrieveSymbolicTensors(n),r=new T.RW;if(e instanceof i.qYS&&(e=[e]),Array.isArray(e)){if(e.length!==this.inputs.length)throw new a.Qp(`The number of inputs provided (${e.length}) does not match the number of inputs of this model (${this.inputs.length}).`);for(let t=0;t<this.inputs.length;++t)r.add(this.inputs[t],e[t])}else for(let t of this.inputs){let s=e[t.name];if(null==s)throw new a.Qp(`No value is provided for the model's input ${t.name}`);r.add(t,s)}let o=(0,T.g7)(l,r);return s?o:o[0]}retrieveSymbolicTensors(e){let t=(0,d.fD)(null,e.length),s=e.length;for(let i of this.layers){let n=Array.isArray(i.output)?i.output:[i.output],l=n.map(e=>e.name);for(let i=0;i<e.length;++i){let r=l.indexOf(e[i]);if(-1!==r&&(t[i]=n[r],s--),0===s)break}if(0===s)break}if(s>0){let s=[];throw t.forEach((t,i)=>{null==t&&s.push(e[i])}),new a.Qp(`Cannot find SymbolicTensors for output name(s): ${JSON.stringify(s)}`)}return t}predictLoop(e,t=32,s=!1){return i.DZQ(()=>{let n=this.checkNumSamples(e);if(s)throw new a.EH("Verbose predictLoop() is not implemented yet.");let l=(0,$.XX)(n,t),r=this.outputs.map(e=>[]);for(let t=0;t<l.length;++t)i.DZQ(()=>{let s=l[t][0],i=l[t][1],n=(0,$.Pe)(e,s,i),r=[];if(Array.isArray(n))for(let e=0;e<n.length;++e)r.push({key:this.inputs[e],value:n[e]});else r.push({key:this.inputs[0],value:n});let a=new T.RW(r);return(0,T.g7)(this.outputs,a)}
1).forEach((e,t)=>r[t].push(e));return(0,d.wL)(r.map(e=>i.xWs(e,0)))})}predict(e,t={}){let s=(0,$.n4)(e);S(s,this.inputNames,this.feedInputShapes,!1);try{let e=null==t.batchSize?32:t.batchSize;return(0,$.yy)(e),this.predictLoop(s,e)}finally{(0,$.Ec)(s,e)}}predictOnBatch(e){S(e,this.inputNames,this.feedInputShapes,!0);let t=(Array.isArray(e)?e[0]:e).shape[0];return this.predictLoop(e,t)}standardizeUserDataXY(e,t,s=!0,n){if(null==this.optimizer_)throw new a.bu("You must compile a model before training/testing. Use LayersModel.compile(modelCompileArgs).");let l=[];for(let e=0;e<this.feedOutputShapes.length;++e){let t=this.feedOutputShapes[e];this.feedLossFns[e]===u.qp?l.push(t.slice(0,t.length-1).concat([1])):l.push(t)}e=z(e,this.feedInputNames,this.feedInputShapes,!1,"input"),t=z(t,this.feedOutputNames,l,!1,"target");var r=e,o=t;let h=(0,d.Am)(r.map(e=>e.shape[0]));h.sort();let p=(0,d.Am)(o.map(e=>e.shape[0]));if(p.sort(),h.length>1)throw new a.Qp(`All input Tensors (x) should have the same number of samples. Got array shapes: ${JSON.stringify(r.map(e=>e.shape))}`);if(p.length>1)throw new a.Qp(`All target Tensors (y) should have the same number of samples. Got array shapes: ${JSON.stringify(o.map(e=>e.shape))}`);if(h.length>0&&p.length>0&&!i.ZSL.arraysEqual(h,p))throw new a.Qp(`Input Tensors should have the same number of samples as target Tensors. Found ${h[0]} input sample(s) and ${p[0]} target sample(s).`);if(!function(e,t,s){let i=[u.bt,u.Jc,u.Ol];for(let n=0;n<e.length;++n){let l=e[n],r=t[n],o=s[n];if(null!=r){if(r===u.Ol&&1===l.shape[l.shape.length-1])throw new a.Qp(`You are passing a target array of shape ${l.shape} while using a loss 'categorical_crossentropy'. 'categorical_crossentropy'expects targets to be binary matrices (1s and 0s) of shape [samples, classes].`);if(-1!==i.indexOf(r)){let e=l.shape.slice(1),t=o.slice(1);for(let s=0;s<e.length;++s){let i=e[s],n=t[s];if(null!=n&&i!==n)throw new a.Qp(`A target Tensor with shape ${l.shape} was passed for an output of shape ${o}, while using a loss function that expects targets to have the same shape as the output.`)}}}}}(t,this.feedLossFns,this.feedOutputShapes),this.stateful&&null!=n&&n>0&&e[0].shape[0]%n!=0)throw new a.Qp(`In a stateful network, you should only pass inputs with a number of samples that is divisible by the batch size ${n}. Found: ${e[0].shape[0]} sample(s).`);return[e,t]}async standardizeUserData(e,t,s,i,n=!0,l){let[r,a]=this.standardizeUserDataXY(e,t,n,l);if(null!=s)throw Error("sample weight is not supported yet.");let o=null;if(null!=i){let e=(0,O.zO)(i,this.outputNames);o=[];for(let t=0;t<e.length;++t)o.push(await (0,O.tP)(a[t],null,e[t]))}return[r,a,o]}testLoop(e,t,s,l=0,r){return i.DZQ(()=>{let o=this.checkNumSamples(t,s,r,"steps"),h=[];if(l>0)throw new a.EH("Verbose mode is not implemented yet.");if(null!=r)throw new a.EH("steps mode in testLoop() is not implemented yet");{let l=(0,$.XX)(o,s),r=(0,i.tGX)((0,m.y1)(0,o));for(let s=0;s<l.length;++s){let a=l[s][0],o=l[s][1],u=n.Dh(r,a,o-a),p=e((0,$.DE)(t,u));if(0===s)for(let e=0;e<p.length;++e)h.push((0,i.d_2)(0));for(let e=0;e<p.length;++e){let t=p[e];h[e]=i.WQq(h[e],i.lKK(o-a,t))}}for(let e=0;e<h.length;++e)h[e]=i.y4m(h[e],o)}return h})}getDedupedMetricsNames(){let e=this.metricsNames,t=[];for(let s=0;s<e.length;++s){let i=e[s],n=i;if((0,d.U9)(e,i)>1){let t=(0,d.U9)(e.slice(0,s),i);n+=`_${t}`}t.push(n)}return t}makeTrainFunction(){return e=>{let t=[],s=e.slice(0,this.inputs.length),n=e.slice(this.inputs.length,this.inputs.length+this.outputs.length),l=e.slice(this.inputs.length+this.outputs.length,this.inputs.length+2*this.outputs.length),r=[],a=()=>{let e,a=[];for(let e=0;e<this.inputs.length;++e)a.push({key:this.inputs[e],value:s[e]});let o=new T.RW(a),h=(0,T.g7)(this.outputs,o,{training:!0});for(let s=0;s<this.lossFunctions.length;++s){let r=(0,this.lossFunctions[s])(n[s],h[s]);null!=l[s]&&(r=(0,O.M5)(r,l[s]));let a=i.i2o(r);t.push(a),e=0===s?r:i.WQq(e,r)}for(let e=0;e<this.metricsTensors.length;++e){let s;if(this.outputs.length>1&&e<this.outputs.length)s=t[e];else{let t=this.metricsTensors[e][0],l=this.metricsTensors[e][1];s=i.i2o(t(n[l],h[l]))}i.aCs(s),r.push(s)}
1return e=i.i2o(e),this.calculateLosses().forEach(t=>{e=i.WQq(e,t)}),e},o=this.collectedTrainableWeights.map(e=>e.read());return[this.optimizer_.minimize(a,!0,o)].concat(r)}}makeTestFunction(){this.testFunction=e=>i.DZQ(()=>{let t,s=[],n=e.slice(0,this.inputs.length),l=e.slice(this.inputs.length,this.inputs.length+this.outputs.length),r=[];for(let e=0;e<this.inputs.length;++e)r.push({key:this.inputs[e],value:n[e]});let a=new T.RW(r),o=(0,T.g7)(this.outputs,a);for(let e=0;e<this.lossFunctions.length;++e){let n=this.lossFunctions[e],r=i.i2o(n(l[e],o[e]));t=0===e?r:i.WQq(t,r),s.push(t)}for(let e=0;e<this.metricsTensors.length;++e){let t=this.metricsTensors[e][0],n=this.metricsTensors[e][1],r=i.i2o(t(l[n],o[n]));s.push(r)}return s})}async fit(e,t,s={}){let n,r,o,h,u,p,c,f,d;if(this.isTraining)throw Error("Cannot start training because another fit() call is ongoing.");this.isTraining=!0;try{let i,g,m,y=null==s.batchSize?32:s.batchSize;(0,$.yy)(y);let w=await this.standardizeUserData(e,t,s.sampleWeight,s.classWeight,!1,y);n=w[0],r=w[1],d=w[2];let b=!1;if(null!=s.validationData&&s.validationData.length>0){if(b=!0,2===s.validationData.length)u=s.validationData[0],p=s.validationData[1];else if(3===s.validationData.length)throw new a.EH("validationData including sample weights is not supported yet.");else throw new a.Qp(`When passing validation data, it must contain 2 (valX, valY) or 3 (valX, valY, valSampleWeight) items; ${s.validationData} is invalid.`);let e=await this.standardizeUserData(u,p,null,null,!0,y);c=e[0],f=e[1],i=c.concat(f)}else if(null!=s.validationSplit&&s.validationSplit>0&&s.validationSplit<1){b=!0;let e=Math.floor(n[0].shape[0]*(1-s.validationSplit)),t=n[0].shape[0];c=(0,$.Pe)(n,e,t),o=n,n=(0,$.Pe)(n,0,e),f=(0,$.Pe)(r,e,t),h=r,r=(0,$.Pe)(r,0,e),i=c.concat(f)}else null!=s.validationSteps&&(b=!0);let T=n.concat(r).concat(d);this.checkTrainableWeightsConsistency();let v=this.makeTrainFunction(),O=this.getDedupedMetricsNames();b?(this.makeTestFunction(),g=this.testFunction,m=O.slice().concat(O.map(e=>"val_"+e))):(g=null,i=[],m=O.slice());let E=(0,l.Eq)(s.callbacks,s.yieldEvery);return await this.fitLoop(v,T,O,y,s.epochs,s.verbose,E,g,i,s.shuffle,m,s.initialEpoch,null,null)}finally{this.isTraining=!1,(0,$.Ec)(n,e),(0,$.Ec)(r,t),(0,$.Ec)(o,e),(0,$.Ec)(h,t),(0,$.Ec)(c,u),(0,$.Ec)(f,p),null!=d&&i.ASo(d)}}async fitLoop(e,t,s,r,o,u,p,c,f,d,g,y,w,b){let T;null==r&&(r=32),null==o&&(o=1),null==d&&(d=!0),null==y&&(y=0);let v=!1;if(null!=c&&null!=f&&(v=!0),null!=b&&(v=!0,null==w))throw new a.Qp("Can only use `validationSteps` when doing step-wise training, i.e., `stepsPerEpoch` must be set.");let O=this.checkNumSamples(t,r,w,"steps_per_epoch");null!=O&&(T=(0,m.y1)(0,O)),null==u&&(u=1);let{callbackList:E,history:A}=(0,l.dY)(p,u,o,y,O,w,r,v,g);E.setModel(this),this.history=A,await E.onTrainBegin(),this.stopTraining_=!1;for(let l=y;l<o;++l){await E.onEpochBegin(l);let o={};if(null!=w)throw new a.EH("stepsPerEpoch mode is not implemented yet.");{if("batch"===d)throw new a.EH("batch shuffling is not implemneted yet");d&&i.ZSL.shuffle(T);let l=(0,i.tGX)(T),u=(0,$.XX)(O,r);for(let a=0;a<u.length;++a){let p={};if(await E.onBatchBegin(a,p),i.DZQ(()=>{let h=u[a][0],d=u[a][1],g=n.Dh(l,h,d-h);p.batch=a,p.size=d-h;let m=e((0,$.DE)(t,g));for(let e=0;e<s.length;++e){let t=s[e],n=m[e];p[t]=n,i.aCs(n)}if(a===u.length-1&&v){let e=this.testLoop(c,f,r);for(let t=0;t<s.length;++t){let n=s[t],l=e[t];i.aCs(l),o["val_"+n]=l}}}),await E.onBatchEnd(a,p),(0,h.i)(p),this.stopTraining_)break}l.dispose()}if(await E.onEpochEnd(l,o),this.stopTraining_)break}return await E.onTrainEnd(),await this.history.syncData(),this.history}async fitDataset(e,t){return(0,v.O)(this,e,t)}async trainOnBatch(e,t){let s=await this.standardizeUserData(e,t),n=s[0],l=s[1],r=this.makeTrainFunction()(n.concat(l)),a=[];for(let e of r){let t=await e.data();a.push(t[0])}return i.ASo(r),(0,$.Ec)(s[0],e),(0,$.Ec)(s[1],t),(0,d.wL)(a)}getNamedWeights(e){let t=[],s=null!=e&&e.trainableOnly,i=s?this.trainableWeights:this.weights,n=this.getWeights(s);for(let e=0;e<i.length;++e)(!s||i[e].trainable)&&t.push({name:i[e].originalName,tensor:n[e]});return t}set stopTraining(e){this.stopTraining_=e}get stopTraining(){return this.stopTraining_}get optimizer(){return this.optimizer_}set optimizer(e){this.optimizer_!==e&&(this.optimizer_=e,this.isOptimizerOwned=!1)}dispose(){let e=super.dispose();if(0===e.refCountAfterDispose&&null!=this.optimizer&&this.isOptimizerOwned){let t=i.m1Z().numTensors;this.optimizer_.dispose(),e.numDisposedVariables+=t-i.m1Z().numTensors}return e}getLossIdentifiers(){let e;if("string"==typeof this.loss)e=(0,d.uc)(this.loss);else if(Array.isArray(this.loss)){for(let e of this.loss)if("string"!=typeof e)throw Error("Serialization of non-string loss is not supported.");e=this.loss.map(e=>(0,d.uc)(e))}else{let t=Object.keys(this.loss);e={};let s=this.loss;for(let i of t)if("string"==typeof s[i])e[i]=(0,d.uc)(s[i]);else throw Error("Serialization of non-string loss is not supported.")}return e}getMetricIdentifiers(){if("string"==typeof this.metrics||"function"==typeof this.metrics)return[(0,d.uc)(p.GT(this.metrics))];{if(Array.isArray(this.metrics))return this.metrics.map(e=>(0,d.uc)(p.GT(e)));let e={};for(let t in this.metrics)e[t]=(0,d.uc)(p.GT(this.metrics[t]));return e}}getTrainingConfig(){return{loss:this.getLossIdentifiers(),metrics:this.getMetricIdentifiers(),optimizer_config:{class_name:this.optimizer.getClassName(),config:this.optimizer.getConfig()}}}loadTrainingConfig(e){let t,s;if(null!=e.weighted_metrics)throw Error("Loading weight_metrics is not supported yet.");if(null!=e.loss_weights)throw Error("Loading loss_weights is not supported yet.");if(null!=e.sample_weight_mode)throw Error("Loading sample_weight_mode is not supported yet.");let i=(0,y.w)(e.optimizer_config),n=(0,o.i)(i);if("string"==typeof e.loss)t=(0,d.Cb)(e.loss);else if(Array.isArray(e.loss))t=e.loss.map(e=>(0,d.Cb)(e));else if(null!=e.loss)for(let s in t={},e.loss)t[s]=(0,d.Cb)(e.loss[s]);if(Array.isArray(e.metrics))s=e.metrics.map(e=>(0,d.Cb)(e));else if(null!=e.metrics)for(let t in s={},e.metrics)s[t]=(0,d.Cb)(e.metrics[t]);this.compile({loss:t,metrics:s,optimizer:n})}async save(e,t){if("string"==typeof e){let t=i.io.getSaveHandlers(e);if(0===t.length)throw new a.Qp(`Cannot find any save handlers for URL '${e}'`);if(t.length>1)throw new a.Qp(`Found more than one (${t.length}) save handlers for URL '${e}'`);e=t[0]}if(null==e.save)throw new a.Qp("LayersModel.save() cannot proceed because the IOHandler provided does not have the `save` attribute defined.");let s=await i.io.encodeWeights(this.getNamedWeights(t)),n={modelTopology:this.toJSON(null,!1),format:"layers-model",generatedBy:`TensorFlow.js tfjs-layers v${w.r}`,convertedBy:null};if(null!=t&&t.includeOptimizer&&null!=this.optimizer){n.trainingConfig=this.getTrainingConfig();let{data:e,specs:t}=await i.io.encodeWeights(await this.optimizer.getWeights(),"optimizer");s.specs.push(...t),s.data=i.io.concatenateArrayBuffers([s.data,e])}return null!=this.userDefinedMetadata&&((0,f.Yl)(this.userDefinedMetadata,this.name,!0),n.userDefinedMetadata=this.userDefinedMetadata),n.weightData=s.data,n.weightSpecs=s.specs,e.save(n)}setUserDefinedMetadata(e){(0,f.Yl)(e,this.name),this.userDefinedMetadata=e}getUserDefinedMetadata(){return this.userDefinedMetadata}}N.className="Model",i.JFn.registerClass(N);class D extends N{}D.className="Functional",i.JFn.registerClass(D)}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.