diff --git a/precise/functions.py b/precise/functions.py index 769b5dfa..71989340 100644 --- a/precise/functions.py +++ b/precise/functions.py @@ -83,7 +83,7 @@ def false_neg(yt, yp) -> Any: def load_keras() -> Any: """Imports Keras injecting custom functions to prevent exceptions""" - import keras + import tensorflow.keras as keras keras.losses.weighted_log_loss = weighted_log_loss keras.metrics.false_pos = false_pos keras.metrics.false_positives = false_pos diff --git a/precise/model.py b/precise/model.py index cd88aa54..59e1faf9 100644 --- a/precise/model.py +++ b/precise/model.py @@ -22,7 +22,7 @@ from precise.params import inject_params, pr if TYPE_CHECKING: - from keras.models import Sequential + from tensorflow.keras import Sequential @attr.s() @@ -51,7 +51,7 @@ def load_precise_model(model_name: str) -> Any: print('Warning: Unknown model type, ', model_name) inject_params(model_name) - return load_keras().models.load_model(model_name) + return load_keras().models.load_model(model_name, custom_objects={"weighted_log_loss": weighted_log_loss}) def create_model(model_name: Optional[str], params: ModelParams) -> 'Sequential': @@ -69,9 +69,9 @@ def create_model(model_name: Optional[str], params: ModelParams) -> 'Sequential' print('Loading from ' + model_name + '...') model = load_precise_model(model_name) else: - from keras.layers.core import Dense - from keras.layers.recurrent import GRU - from keras.models import Sequential + from tensorflow.keras.layers import Dense + from tensorflow.keras.layers import GRU + from tensorflow.keras import Sequential model = Sequential() model.add(GRU( diff --git a/precise/network_runner.py b/precise/network_runner.py index 7f09d5aa..d8d9baf9 100644 --- a/precise/network_runner.py +++ b/precise/network_runner.py @@ -53,11 +53,11 @@ def __init__(self, model_name: str): self.inp_var = self.graph.get_operation_by_name('import/net_input').outputs[0] self.out_var = self.graph.get_operation_by_name('import/net_output').outputs[0] - self.sess = self.tf.Session(graph=self.graph) + self.sess = self.tf.compat.v1.Session(graph=self.graph) def load_graph(self, model_file: str) -> 'tf.Graph': graph = self.tf.Graph() - graph_def = self.tf.GraphDef() + graph_def = self.tf.compat.v1.GraphDef() with open(model_file, "rb") as f: graph_def.ParseFromString(f.read()) @@ -78,18 +78,10 @@ class KerasRunner(Runner): """ Executes a regular Keras model created from precise-train""" def __init__(self, model_name: str): import tensorflow as tf - # ISSUE 88 - Following 3 lines added to resolve issue 88 - JM 2020-02-04 per liny90626 - from tensorflow.python.keras.backend import set_session # ISSUE 88 - self.sess = tf.Session() # ISSUE 88 - set_session(self.sess) # ISSUE 88 self.model = load_precise_model(model_name) - self.graph = tf.get_default_graph() def predict(self, inputs: np.ndarray): - from tensorflow.python.keras.backend import set_session # ISSUE 88 - with self.graph.as_default(): - set_session(self.sess) # ISSUE 88 - return self.model.predict(inputs) + return self.model.predict(inputs) def run(self, inp: np.ndarray) -> float: return self.predict(inp[np.newaxis])[0][0] diff --git a/precise/params.py b/precise/params.py index f4c1d0ff..1125feaa 100644 --- a/precise/params.py +++ b/precise/params.py @@ -23,6 +23,7 @@ import json import hashlib from os.path import isfile +from os import makedirs @attr.s(frozen=True) @@ -161,5 +162,6 @@ def inject_params(model_name: str) -> ListenerParams: def save_params(model_name: str): """Save current global listener params to a file""" + makedirs(model_name, exist_ok=True) with open(model_name + '.params', 'w') as f: json.dump(pr.__dict__, f) diff --git a/precise/scripts/convert.py b/precise/scripts/convert.py index 20a30083..eee888fa 100755 --- a/precise/scripts/convert.py +++ b/precise/scripts/convert.py @@ -48,39 +48,38 @@ def convert(self, model_path: str, out_file: str): """ print('Converting', model_path, 'to', out_file, '...') - import tensorflow as tf + import tensorflow.compat.v1 as tf from precise.model import load_precise_model - from keras import backend as K + from tensorflow.compat.v1.keras import backend as K out_dir, filename = split(out_file) out_dir = out_dir or '.' os.makedirs(out_dir, exist_ok=True) K.set_learning_phase(0) - model = load_precise_model(model_path) - - out_name = 'net_output' - tf.identity(model.output, name=out_name) - print('Output node name:', out_name) - print('Output folder:', out_dir) - sess = K.get_session() + with sess.graph.as_default(): + model = load_precise_model(model_path) + + out_name = 'net_output' + tf.identity(model.output, name=out_name) + print('Output node name:', out_name) + print('Output folder:', out_dir) - # Write the graph in human readable - tf.train.write_graph(sess.graph.as_graph_def(), out_dir, filename + 'txt', as_text=True) - print('Saved readable graph to:', filename + 'txt') + # Write the graph in human readable + tf.train.write_graph(sess.graph.as_graph_def(), out_dir, filename + 'txt', as_text=True) + print('Saved readable graph to:', filename + 'txt') - # Write the graph in binary .pb file - from tensorflow.python.framework import graph_util - from tensorflow.python.framework import graph_io + # Write the graph in binary .pb file + from tensorflow.python.framework import graph_io - cgraph = graph_util.convert_variables_to_constants(sess, sess.graph.as_graph_def(), [out_name]) - graph_io.write_graph(cgraph, out_dir, filename, as_text=False) + cgraph = tf.graph_util.convert_variables_to_constants(sess, sess.graph.as_graph_def(), [out_name]) + graph_io.write_graph(cgraph, out_dir, filename, as_text=False) - if isfile(model_path + '.params'): - copyfile(model_path + '.params', out_file + '.params') + if isfile(model_path + '.params'): + copyfile(model_path + '.params', out_file + '.params') - print('Saved graph to:', filename) + print('Saved graph to:', filename) del sess diff --git a/precise/scripts/train.py b/precise/scripts/train.py index c9955547..8f9c5f2b 100755 --- a/precise/scripts/train.py +++ b/precise/scripts/train.py @@ -54,7 +54,7 @@ ... """ -from fitipy import Fitipy +from fitipy import FList from keras.callbacks import LambdaCallback from os.path import splitext, isfile from prettyparse import Usage @@ -90,12 +90,12 @@ def __init__(self, args): from keras.callbacks import ModelCheckpoint, TensorBoard checkpoint = ModelCheckpoint(args.model, monitor=args.metric_monitor, save_best_only=args.save_best) - epoch_fiti = Fitipy(splitext(args.model)[0] + '.epoch') - self.epoch = epoch_fiti.read().read(0, int) + epoch_fiti = FList(splitext(args.model)[0] + '.epoch') + self.epoch = int(epoch_fiti.data[0]) if len(epoch_fiti.data) else 0 def on_epoch_end(_a, _b): self.epoch += 1 - epoch_fiti.write().write(self.epoch, str) + epoch_fiti.append(self.epoch) self.model_base = splitext(self.args.model)[0] @@ -113,7 +113,7 @@ def on_epoch_end(_a, _b): @staticmethod def load_sample_data(filename, train_data) -> Tuple[set, dict]: - samples = Fitipy(filename).read().set() + samples = set(FList(filename).data) hash_to_ind = { calc_sample_hash(inp, outp): ind for ind, (inp, outp) in enumerate(zip(*train_data)) diff --git a/precise/util.py b/precise/util.py index 4971eccf..a869a0b7 100644 --- a/precise/util.py +++ b/precise/util.py @@ -69,7 +69,7 @@ def save_audio(filename: str, audio: np.ndarray): """Save loaded audio to file using the configured audio parameters""" import wavio save_audio = (audio * np.iinfo(np.int16).max).astype(np.int16) - wavio.write(filename, save_audio, pr.sample_rate, sampwidth=pr.sample_depth, scale='none') + wavio.write(filename, save_audio, pr.sample_rate, sampwidth=pr.sample_depth) def play_audio(filename: str): diff --git a/requirements.txt b/requirements.txt index 38f303f4..58741b81 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,44 +1,39 @@ -absl-py==0.7.1 -astor==0.7.1 -attrs==19.1.0 -cycler==0.10.0 -decorator==4.4.0 -fitipy==0.1.2 -future==0.17.1 -gast==0.2.2 -grpcio==1.19.0 -h5py==2.9.0 -Keras==2.2.4 -Keras-Applications==1.0.7 -Keras-Preprocessing==1.0.9 -kiwisolver==1.0.1 -Markdown==3.1 -matplotlib==3.0.3 -mock==2.0.0 --e git+git@github.com:MycroftAI/mycroft-precise@37ef1ab91eeca81fd889bce2967775b2f6918d97#egg=mycroft_precise -numpy==1.16.2 -pbr==5.1.3 -pocketsphinx==0.1.15 -portalocker==1.4.0 --e git+git@github.com:MycroftAI/mycroft-precise@37ef1ab91eeca81fd889bce2967775b2f6918d97#egg=precise_runner&subdirectory=runner -prettyparse==0.1.4 -protobuf==3.7.1 -PyAudio==0.2.11 -pymongo==3.7.2 -pyparsing==2.3.1 -python-dateutil==2.8.0 -PyYAML==5.1 -scikit-learn==0.20.3 -scikit-optimize==0.5.2 -scipy==1.2.1 -six==1.12.0 +absl-py==1.4.0 +astor==0.8.1 +attrs==23.1.0 +cycler==0.11.0 +decorator==5.1.1 +fitipy==1.0.0 +future==0.18.3 +gast==0.4.0 +grpcio==1.54.2 +h5py==3.9.0 +Keras +kiwisolver==1.4.4 +Markdown==3.4.3 +matplotlib==3.7.1 +mock==5.0.2 +numpy==1.23.5 +pbr==5.11.1 +pocketsphinx==5.0.1 +portalocker==2.7.0 +prettyparse==1.2.0 +protobuf==4.23.3 +PyAudio==0.2.13 +pymongo==4.4.0 +pyparsing==3.1.0 +python-dateutil==2.8.2 +PyYAML==6.0 +scikit-learn==1.2.2 +scikit-optimize==0.9.0 +scipy==1.10.1 +six==1.16.0 sonopy==0.1.2 speechpy-fast==2.4 -tensorboard==1.13.1 -tensorflow==1.13.1 -tensorflow-estimator==1.13.0 -termcolor==1.1.0 -tqdm==4.31.1 -typing==3.6.6 -wavio==0.0.4 -Werkzeug==0.15.3 +tensorboard==2.12.3 +tensorflow==2.12.0 +termcolor==2.3.0 +tqdm==4.65.0 +typing==3.7.4.3 +wavio==0.0.7 +Werkzeug==2.3.6 diff --git a/setup.py b/setup.py index 44a9916b..edce76aa 100644 --- a/setup.py +++ b/setup.py @@ -41,6 +41,7 @@ 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.10', ], packages=[ 'precise', @@ -71,11 +72,11 @@ }, include_package_data=True, install_requires=[ - 'numpy==1.16', - 'tensorflow>=1.13,<1.14', # Must be on piwheels + 'numpy', + 'tensorflow', # Must be on piwheels 'sonopy', 'pyaudio', - 'keras<=2.1.5', + 'keras', 'h5py', 'wavio', 'typing', diff --git a/setup.sh b/setup.sh index 1c8a6a0b..0d798826 100755 --- a/setup.sh +++ b/setup.sh @@ -40,7 +40,8 @@ os=$(uname -s) if [ "$os" = "Linux" ]; then if is_command apt-get; then wait_for_apt - sudo apt-get install -y python3-pip curl libopenblas-dev python3-scipy cython libhdf5-dev python3-h5py portaudio19-dev swig libpulse-dev libatlas-base-dev + sudo apt-get install -y python3-pip curl libopenblas-dev python3-scipy libhdf5-dev python3-h5py portaudio19-dev swig libpulse-dev libatlas-base-dev + sudo pip install cython fi elif [ "$os" = "Darwin" ]; then if is_command brew; then